您如何计算浮点数中设置的位数?

如何使用C函数计算浮点数中设置的位数?

#include  /* for printf() */ #include  /* for CHAR_BIT */ int main(void) { /* union method */ { /* a union can only be initialized for the first option in the union */ union { float f; char cs[sizeof(float)]; } const focs = { 1.0 }; int j,k; int count = 0; for (j = 0; j < sizeof(float); j++) { char const byte = focs.cs[j]; for (k = 0; k < CHAR_BIT; k++) { if ((1 << k) & byte) { count++; } } } printf("count(%2.1f) = %d\n", focs.f, count); } /* cast method */ { float const f = 2.5; int j,k; int count = 0; for (j = 0; j < sizeof(float); j++) { char const byte = ((char *)&f)[j]; for (k = 0; k < CHAR_BIT; k++) { if ((1 << k) & byte) { count++; } } } printf("count(%2.1f) = %d\n", f, count); } return 0; } 

如果要处理浮点数的实际按位表示,则应该执行以下操作:

 float f; /* whatever your float is */ int i = *(int *)&f; 

这样做的地址是f ,地址为运算符& 。 此地址的类型为float * ,指向float的指针。 然后用(int *)重新创建它,它说“假装这个指针不再指向float ,但现在它指向一个int ”。 请注意,它根本不会更改f处的值。 然后最后的* (或者,首先,因为我们从右向左阅读)取消引用这个指针,这是一个指向int的指针,因此返回一个int ,也就是具有与float相同的按位表示的整数。

要做相反的事情(转换并将int i返回到float f ),请执行相反的操作:

 f = *(float *)&i; 

除非我弄错了,否则C标准不会定义此操作,但可能适用于大多数计算机和编译器。 它是未定义的,因为我认为数字的实际浮点表示是依赖于实现的,并且可以留给CPU或编译器,因此在该操作之后几乎不可能预测i的值(值相同) f在反向操作中)。 它在John Carmack的逆平方根函数中用于同样的邪恶目的。

无论如何,如果你在实际代码中这样做,你应该停下来思考你正在尝试做什么以及为什么你使用float来做它。 但是,如果您只是出于好奇而做这件事,或者您已经考虑过这些并且确定您的设计和方法,那就去吧。

我已经相信你已经知道如何计算常规整数中设置的位数,因为这是一个更容易的任务。 如果您不知道,您的编译器(或C语言,我甚至不知道)可能具有计数位的function,或者您可以使用来自精彩Bit-Twiddling Hacks网站的内容,该网站有办法做事像这样的按位运算(应该非常快)。

一个很好的函数,用于计算第一个答案提到的整数中的设置位:

 int NumberOfSetBits(int i) { i = i - ((i >> 1) & 0x55555555); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; } 

要在你的浮动上使用它你会做这样的事情:

 //... float f; //... int numBitsOfF = NumberOfSetBits(*(int*) &f); 

你的意思是在一个数字的IEEE-754单精度表示中设置的位? 如果是这样,将它转换为int(float和int都是32位宽)并进行常规位计数: 问题#109023 。

 The following function will find the number of bits in a 32-bit number. Just type case your float with integer and call this function by a cast float f=3.14f; count_bits(*(int *)&f); int count_bits(int v) { // count the number of bits set in v int c; // c accumulates the total bits set in v int b=v; for (c = 0; v; c++) { v &= v - 1; // clear the least significant bit set } //printf("No of bits in %d is %d\n",b,c); return c; }