两个浮点值(IEEE 754 binary64)可以作为整数进行比较吗?例如。
long long a = * (long long *) ptr_to_double1,
b = * (long long *) ptr_to_double2;
if (a < b) {...}
假设
long long
和 double
的大小相同。
最佳答案
不可以。两个浮点值(IEEE 754 binary64)不能简单地作为整数与 if (a < b)
进行比较。
IEEE 754 binary64double
值的顺序与整数的顺序不同(除非您使用的是罕见的符号大小机器)。考虑正数与负数。double
具有类似 0.0
和 -0.0
的值,它们具有相同的值但不同的位模式。double
具有与它们的二进制等效整数表示不同的“非数字”。
如果 double
值都是 x > 0
而不是“非数字”,则字节序、混叠和对齐等都不是问题,OP 的想法会奏效。
或者,可以使用更复杂的 if() ...
条件 - 见下文
[非 IEEE 754 binary64]
一些 double
使用一种编码,其中有多个相同值的表示。这将不同于“整数”比较。
测试代码:需要 2 的补码,double
和整数的字节序相同,不考虑 NaN。
int compare(double a, double b) {
union {
double d;
int64_t i64;
uint64_t u64;
} ua, ub;
ua.d = a;
ub.d = b;
// Cope with -0.0 right away
if (ua.u64 == 0x8000000000000000) ua.u64 = 0;
if (ub.u64 == 0x8000000000000000) ub.u64 = 0;
// Signs differ?
if ((ua.i64 < 0) != (ub.i64 < 0)) {
return ua.i64 >= 0 ? 1 : -1;
}
// If numbers are negative
if (ua.i64 < 0) {
ua.u64 = -ua.u64;
ub.u64 = -ub.u64;
}
return (ua.u64 > ub.u64) - (ua.u64 < ub.u64);
}
感谢 @David C. Rankin 的更正。
测试代码
void testcmp(double a, double b) {
int t1 = (a > b) - (a < b);
int t2 = compare(a, b);
if (t1 != t2) {
printf("%le %le %d %d\n", a, b, t1, t2);
}
}
#include <float.h>
void testcmps() {
// Various interesting `double`
static const double a[] = {
-1.0 / 0.0, -DBL_MAX, -1.0, -DBL_MIN, -0.0,
+0.0, DBL_MIN, 1.0, DBL_MAX, +1.0 / 0.0 };
int n = sizeof a / sizeof a[0];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
testcmp(a[i], a[j]);
}
}
puts("!");
}
关于将 float 与整数进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33678827/