如何在C语言中检测有符号整数的编码?

如何在C语言中检测有符号整数的编码?,c,signed,twos-complement,ones-complement,C,Signed,Twos Complement,Ones Complement,ISO C标准允许有符号整数的三种编码方法:二的补码、一的补码和符号/幅度 在运行时(或者如果有更好的解决方案,其他时间)检测编码的有效或好方法是什么?我想知道这一点,这样我就可以为不同的可能性优化bignum库 我计划在每次程序运行时计算它并将其存储在一个变量中,这样它就不必太快了——我假设在程序运行期间编码不会改变:-)检测一个人的补码应该非常简单——类似于if(-x==x)。检测二的补码应该同样容易:if(-x==~x+1)。如果两者都不是,那么它必须是符号/量级。为什么不在编译时执行呢?

ISO C标准允许有符号整数的三种编码方法:二的补码、一的补码和符号/幅度

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


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

检测一个人的补码应该非常简单——类似于
if(-x==x)
。检测二的补码应该同样容易:
if(-x==~x+1)
。如果两者都不是,那么它必须是符号/量级。

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

我想您应该将一个负数作为
int
存储到一个足够大的
char
数组中,并将该数组与各种表示形式进行比较以找出答案


但是嗯。。。无符号整数不应该有符号,是吗?

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


使用几个精心选择的值执行此操作应该可以满足您的需要。

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

  • 对于符号和大小
  • 补足
  • 两个人的互补

  • 这甚至可以在
    #if#else
    构造中的预处理器表达式中实现。

    是的。。。看来我想的太复杂了。。。Jerry关于使用位操作检查的说法是对的。不要介意。把它留在这里作为另一个答案。是的,对不起,那应该是有符号的。这些也是常量表达式,所以你可以在
    \if
    测试中使用它们:
    \define twoscomplete(~-1==0)
    然后
    \if twoscomplete
    。不过,你的表达式不一定适用于
    x
    的所有情况,所以你应该小心处理边境案件。特别是对于两个补码,
    -x
    会引发未定义的行为,即
    -INT\u MIN
    可能超出范围。您永远不需要在运行时这样做-在为特定体系结构编译时,这纯粹是编译时的问题。对于bignum库,您几乎总是需要无符号类型。虽然您可以对最高顺序的字使用有符号类型,但只存储一个单独的符号位并始终使用正数,然后根据符号位翻转加法/减法的含义可能更简单。基本上你自己的符号/大小表示法。@Jens Gustedt的回答很好!但是在交叉编译期间,这里究竟检查了什么,编译器(预处理器)的编码还是目标机器的编码?@user2596047,编译器必须始终像在运行时一样计算所有表达式,以便生成代码的执行行为与所谓的“抽象状态机”中的行为相同。所以是的,即使是交叉编译,也必须在目标机器的算法中完成,而不是在主机上。