我编写了一个函数,该函数适用于数百种情况,但在某些情况下会失败。
这是 C 函数:
unsigned negate_number(unsigned x) {
int sign = (!(x & 0x80000000))<<31;
int other = 0x7FFFFFFF & x;
return (sign | other);
}
我只是屏蔽符号,将其反转并与屏蔽指数和曼特萨进行 OR(连接)。所以这应该适用于所有情况。
但这里有一个失败的情况: x = 0x7fc00000 (2143289344)
最佳答案
我问:
Why are you asking about 'floating number' in the title when the code is working with integers? Are you trying to call the function with a
float
and treat it as an array of bits, more or less? If so, you're on a hiding to nothing! If you call the function with a prototype in scope, the C compiler will convert thefloat
to anunsigned int
. If you don't call it with a prototype in scope, the C compiler will convert thefloat
to adouble
before calling the function.
回应是:
It is a 32 bit IEEE 754 single precision number. So I am just flipping the most significant bit (sign bit).
要翻转 32 位(无符号整数)数量的最高有效位,您可以简单地编写:
x ^= 0x80000000;
但是,正如我所指出的,除非您对编译器撒谎,否则根本不会传递 32 位 float 。如果你有以下条件,你就可以“让它工作”(在某些机器上,有时):
虚假代码
文件A.c
extern float negate_number(float x);
...
float f1 = 3.14159;
float f2 = negate_number(f1);
...
文件B.c
unsigned negate_number(unsigned x)
{
return x ^ 0x80000000;
}
但是,您正在对编译器玩火和撒谎。编译器讨厌被欺骗,并且经常想办法挽回自己的损失。 不要这样做!
主要是犹太洁食代码
要以最少的问题(但不是“没有问题”)或多或少地实现您想要的效果,您可能需要:
文件B.c
float negate_number(float f)
{
union { unsigned x; float y; } u;
u.y = f;
u.x ^= 0x80000000;
return u.y;
}
严格来说,在分配给 u.y
后读取和写入 u.x
是未定义的行为,但它通常会执行您想要的操作;与操作 u.x
后返回 u.y
类似。
所有这些都假设 float
和 unsigned
的位布局使得 float
的符号位是最高有效位无符号
。
关于c - 在某些情况下,c 中的负 float 会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12336675/