[英]Sign of a floating point number
有没有一种简单的方法来确定浮点数的符号?
我进行了实验并提出了这个:
#include <iostream>
int main(int argc, char** argv)
{
union
{
float f;
char c[4];
};
f = -0.0f;
std::cout << (c[3] & 0x10000000) << "\n";
std::cin.ignore();
std::cin.get();
return 0;
}
其中 (c[3] & 0x10000000) 给出一个值 > 0 表示负数,但我认为这需要我做出以下假设:
如果这些假设中有任何错误或我遗漏了任何假设,请纠正我。
使用 math.h 中的 signbit()。
尝试
float s = copysign(1, f);
来自<math.h>
另一个有用的东西可能是 #include <ieee754.h>
,如果它在您的系统/编译器上可用。
假设它是一个有效的浮点数(而不是,例如,NaN):
float f;
bool is_negative = f < 0;
留给读者的练习是弄清楚如何测试浮点数是否为正数。
1) sizeof(int) 与它无关。
2) 假设 CHAR_BIT == 8,是的。
3)我们需要MSB,但字节序只影响字节顺序,而不是位顺序,所以我们需要检查的位是c[0]&0x80
表示大端,或c[3]&0x80
表示小,所以会更好用uint32_t
声明联合并检查 0x80000000。
这个技巧只对非特殊内存操作数有意义。 对 XMM 或 x87 寄存器中的float
值执行此操作将比直接方法慢。 此外,它不会处理像 NaN 或 INF 这样的特殊值。
来得这么晚,但我想到了另一种方法。
如果您知道您的系统使用 IEEE754 浮点格式,但不知道浮点类型相对于整数类型有多大,您可以执行以下操作:
bool isFloatIEEE754Negative(float f)
{
float d = f;
if (sizeof(float)==sizeof(unsigned short int)) {
return (*(unsigned short int *)(&d) >> (sizeof(unsigned short int)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned int)) {
return (*(unsigned int *)(&d) >> (sizeof(unsigned int)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned long)) {
return (*(unsigned long *)(&d) >> (sizeof(unsigned long)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned char)) {
return (*(unsigned char *)(&d) >> (sizeof(unsigned char)*CHAR_BIT - 1) == 1);
}
else if (sizeof(float)==sizeof(unsigned long long)) {
return (*(unsigned long long *)(&d) >> (sizeof(unsigned long long)*CHAR_BIT - 1) == 1);
}
return false; // Should never get here if you've covered all the potential types!
}
本质上,您将浮点数中的字节视为无符号整数类型,然后将除一位(符号位)以外的所有位右移不存在。 '>>' 的工作与字节顺序无关,因此这绕过了该问题。
如果可以在执行前确定哪个无符号整数类型与浮点类型的长度相同,则可以将其缩写为:
#define FLOAT_EQUIV_AS_UINT unsigned int // or whatever it is
bool isFloatIEEE754Negative(float f)
{
float d = f;
return (*(FLOAT_EQUIV_AS_UINT *)(&d) >> (sizeof(FLOAT_EQUIV_AS_UINT)*CHAR_BIT - 1) == 1);
}
这适用于我的测试系统; 有人看到任何警告或被忽视的“陷阱”吗?
google 系统的浮点格式。 许多使用 IEEE 754 并且数据中有特定的符号位要检查。 1 为负 0 为正。 其他格式也有类似的东西,而且很容易检查。
请注意,试图让编译器通过硬编码赋值(如 f = -0.0F;)准确地为您提供所需的数字; 可能不起作用。 与浮点格式无关,但与解析器和编译器使用的 C/C++ 库有关。 一般来说,生成负零可能是也可能不是那么简单。
我从http://www.cs.uaf.edu/2008/fall/cs441/lecture/10_07_float.html得到这个试试这个:
/* IEEE floating-point number's bits: sign exponent mantissa */
struct float_bits {
unsigned int fraction:23; /**< Value is binary 1.fraction ("mantissa") */
unsigned int exp:8; /**< Value is 2^(exp-127) */
unsigned int sign:1; /**< 0 for positive, 1 for negative */
};
/* A union is a struct where all the fields *overlap* each other */
union float_dissector {
float f;
struct float_bits b;
};
int main() {
union float_dissector s;
s.f = 16;
printf("float %f sign %u exp %d fraction %u",s.f, s.b.sign,((int)s.b.exp - 127),s.b.fraction);
return 0;
}
(int)(x > 0) - (int)(x < 0);
为什么不if (f < 0.0)
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.