10

有没有一种简单的方法来确定浮点数的符号?

我进行了实验并想出了这个:

#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 的值,但我认为这需要我做出以下假设:

  • 机器的字节是 8 位大
  • 浮点数是 4 个字节大?
  • 机器的最高位是最左边的位(字节序?)

如果这些假设中的任何一个是错误的或者我错过了任何假设,请纠正我。

4

9 回答 9

11

使用 math.h 中的 signbit()。

于 2010-11-20T22:02:43.257 回答
11

尝试

float s = copysign(1, f);

<math.h>

另一个有用的东西可能是 #include <ieee754.h>,如果它在您的系统/编译器上可用。

于 2010-11-20T22:14:17.830 回答
10

假设它是一个有效的浮点数(而不是,例如,NaN):

float f;
bool is_negative = f < 0;

留给读者作为练习来弄清楚如何测试浮点数是否为正。

于 2010-11-20T22:02:21.233 回答
2

1) sizeof(int) 与它无关。

2) 假设 CHAR_BIT == 8,是的。

3)我们需要MSB,但字节序只影响字节顺序,而不影响位序,所以我们需要检查的位是c[0]&0x80大字节序还是c[3]&0x80小字节序,所以最好用an声明联合uint32_t并用0x80000000检查。

这个技巧只对非特殊内存操作数有意义。对 XMM 或 x87 寄存器中的值执行此操作float将比直接方法慢。此外,它不处理 NaN 或 INF 等特殊值。

于 2010-11-20T22:16:36.660 回答
1

谷歌你系统的浮点格式。许多使用 IEEE 754 并且要检查的数据中有特定的符号位。1 为负 0 为正。其他格式也有类似的东西,也很容易检查。

请注意,试图让编译器通过硬编码赋值(如 f = -0.0F;)准确地为您提供所需的数字;可能不起作用。与浮点格式无关,但与解析器和编译器使用的 C/C++ 库有关。一般来说,产生一个负零可能是也可能不是那么微不足道。

于 2010-11-20T22:23:50.360 回答
1

来晚了,但我想到了另一种方法。

如果您知道您的系统使用 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);
}

这适用于我的测试系统;有人看到任何警告或被忽视的“陷阱”吗?

于 2015-06-19T16:01:09.100 回答
0

我从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;
}
于 2012-06-04T01:05:56.297 回答
0
(int)(x > 0) - (int)(x < 0);
于 2021-03-30T05:10:07.273 回答
-1

为什么不if (f < 0.0)呢?

于 2010-11-20T22:03:02.540 回答