如何使用C函数计算浮点数中设置的位数?
#include <stdio.h> /* for printf() */
#include <limits.h> /* 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;
}
int i; int count=0; for (i = 0; i <8 * sizeof(float); i ++){if ((1 <<(i%8))&focs.cs [i / 8]){count ++;}}
来压缩两个循环。 - rampionsizeof(char) == 1
,因为这是通过定义的)。 - rampion如果你想要处理浮点数的位表示,你可以像这样操作:
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;
float
。但是,如果您只是出于好奇心而这样做,或者您已经考虑过这些问题并且确定了您的设计和方法,请去尝试一下。char
)的指针永远不会指向同一对象。 - ephemient第一个答案提到了一种计算整数中设置位的好方法:
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);
memcpy
或union
来安全地进行类型转换。不要强制转换指针;这是严格别名UB。可靠地在C和C++标准之间进行类型转换。对于实际的popcount,可以使用像GNU C __builtin_popcount
这样的内置函数。计算32位整数中设置位的数量。 - Peter Cordes您是指IEEE-754单精度表示中设置的位吗?如果是这样,请将其转换为int(float和int均为32位宽),然后进行常规位计数:SO问题#109023。
unsigned int*)&f
。 无符号类型的表现更好(没有符号混乱)。 - Johannes Schaub - litbThe 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;
}