我最近在c中遇到'〜'运算符。从我收集的数据来看,它只是翻转给定数字的所有位,从而改变其值。所以我玩了一下并编写了这段代码:
第一个程序
#include <stdio.h>
int main(int argc, char *argv[]){
int x = 100;
printf("%d\n", x);
x = ~x;
printf("signed value = %d\nunsigned value = %u\n", x, x);
return 0;
}
带有输出:
100
signed value = -101
unsigned value = 4294967195
但是后来,我试图用浮点数做同样的事情:
第二程序
#include <stdio.h>
int main(int argc, char *argv[]){
float x = 100;
printf("%f\n", x);
x = ~x;
printf("new value = %f\n", x);
return 0;
}
但出现错误:
tests.c:6:6: error: wrong type argument to bit-complement
x = ~x;
因此,我进行了一些研究,发现我们无法在浮点数上使用'〜'运算符。这是真的?如果是,那么我的问题是为什么?
无趣且不令人满意的答案-因为这是指定语言的方式:
6.5.3.3一元算术运算符约束1一元+
或-
运算符的操作数应为算术类型;~
运算符,整数类型;!
运算符的类型,标量类型。
[C 2011 Online Draft] >>
强调我的。
但是,为什么
是用这种方式指定的语言吗?为什么只允许int
运算符用作~
运算符? 嗯,有几种可能的原因。一个,这并不是一种常见的操作(至少在我个人的经验中不是)-很少有使用浮点值的人对这些值的按位操作非常感兴趣。可能有一些问题领域使用了很多,但是我已经有30多年的编程经验了。如果有人真的需要这样做,则只需将双精度浮点数键入或映射到unsigned char
的整数类型或数组上,然后在其中进行位操作,然后映射回原始浮点类型。
两种,浮点格式在历史上一直是变化很大的-尽管当今每个人似乎都已经在IEEE 754上融合了,但是在70年代和80年代,不同的平台都使用浮点来做自己的事情。
[三,请记住,C编译为本地代码-尽管现代的x86确实具有用于按位操作浮点类型的本地指令,但我敢肯定,对于70年代初期的硬件而言,情况并非如此。生成的代码中可能存在足够的性能损失,这是不值得的。