【问题标题】:How to detect encodings on signed integers in C?如何检测C中带符号整数的编码?
【发布时间】:2011-04-18 16:03:03
【问题描述】:

ISO C 标准允许有符号整数的三种编码方法:二进制补码、二进制补码和符号/大小。

在运行时(或其他时间,如果有更好的解决方案)检测编码的有效或好方法是什么?我想知道这一点,以便针对不同的可能性优化 bignum 库。

我计划在每次程序运行时计算它并将其存储在一个变量中,这样它就不必非常快 - 我假设在程序运行期间编码不会改变:-)

【问题讨论】:

  • 您永远不需要在运行时执行此操作 - 在针对特定架构进行编译时,这纯粹是一个编译时问题。
  • 对于 bignum 库,您几乎总是需要无符号类型。虽然您可能能够对最高阶字使用有符号类型,但仅存储一个单独的符号位并始终使用正数可能更简单,然后根据符号位翻转加法/减法的意义。基本上是您自己的符号/幅度表示。

标签: c signed twos-complement ones-complement


【解决方案1】:

您只需要使用-1 & 3 之类的内容检查常量-1 的低位。这评估为

  1. 符号和大小,
  2. 补码和
  3. 补码。

这甚至应该可以在 #if #else 构造内的预处理器表达式中完成。

【讨论】:

  • @Jens Gustedt 的回答非常好!但是在交叉编译的时候,这里到底检查了什么,编译器(预处理器)的编码还是目标机器的编码?
  • @user2596047,编译器必须始终像在运行时评估所有表达式一样评估所有表达式,以便生成代码的执行与所谓的“抽象状态机”中的行为相同。所以是的,即使对于交叉编译,这也必须在目标机器的算术中完成,而不是主机。
【解决方案2】:

获取指向将显示独特位模式的 int 的指针。将其转换为指向 unsigned int 的指针,然后检查位值。

用几个精心挑选的值来做这件事,应该能达到你想要的效果。

【讨论】:

    【解决方案3】:

    我猜你会将一个负数作为 int 存储到一个足够大的 char 数组中,然后将数组与各种表示形式进行比较以找出答案。

    但是呃……无符号整数不应该有符号,是吗?

    【讨论】:

    • 是的……看来我想得太复杂了……杰瑞关于使用位操作进行检查是对的。没关系。将其留在这里作为替代答案。
    • 是的,对不起,应该已经签名了。
    【解决方案4】:

    为什么不在编译时做呢?如果需要,您可以让构建脚本/makefile 编译测试程序,然后使用预处理器进行条件编译。这也意味着性能不那么重要,因为它每次编译只运行一次,而不是每次运行一次。

    【讨论】:

      【解决方案5】:

      检测一个人的补码应该很简单——比如if (-x == ~x)。检测二进制补码应该同样简单:if (-x == ~x + 1)。如果两者都不是,那么它必须是符号/大小。

      【讨论】:

      • 这些也是常量表达式,所以你可以在#if 测试中使用它们:#define TWOSCOMPLEMENT (~-1 == 0) 然后#if TWOSCOMPLEMENT
      • 您的表达式不一定适用于x 的所有情况,因此您应该小心边界情况。特别是二进制补码的这种讨厌的情况,其中-x 会引发未定义的行为,即-INT_MIN 可能超出范围。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多