问题描述
John Harrison 提出的另一个定义略有不同:ULP(x) 是两个最接近的跨浮点数 a 和 b(即 a ≤ x ≤ b 且 a ≠ b)之间的距离,假设指数范围没有上限。
来自 IEEE 754 2008:
2.1.44 量程:有限浮点表示的量程是其有效数最后位置的单位值。这等于将基数提高到指数 q,当有效数被视为整数时使用。
问题:ULP
(John Harrison 的定义)和 quantum
(来自 IEEE 754)有什么区别?
我是否理解正确 double x
的量子可以计算为:
double ulp(double x)
{
int exp;
frexp( x,&exp );
return ldexp( 0.5,exp-52 );
}
double quantum(double x)
{
int exp;
return ulp(frexp( x,&exp ));
}
解决方法
ULP(John Harrison 的定义)和量子(来自 IEEE 754)有什么区别?
[编辑]
OP 的 quantum()
似乎不正确,对于所有有限 1.11022e-16
始终返回 x
,即使 x
是次正态。
答案的其余部分假设 quantum()
更像下面的 quantum_alt()
,对于每个 [power-of-2 ... 2*power-of-2) 都有相同的结果。请注意 [)
。
基数的力量
当 x
是基数的幂时 These definitions differ only at signed powers of the radix
对于 binary64,请考虑 x
何时是 2 的幂。下一个较大的 FP 值是 x + u
,下一个较小的值是 x - u/2
。
John Harrison:“两个最接近的跨浮点数 a 和 b(即 a ≤ x ≤ b 且 a ≠ b)之间的距离”意味着 a
是较小的值,而 {{1 }} 和 ULP 是 x == b
。1
Quantum:“表示是一个单位在其有效数最后一个位置的值”意味着 u/2
是 ULP
。
距离u
是“量子”定义的1/2; b-a
处于比 a
更小的指数子范围内,并且其最后一个有效位置是 x
的一半。
适用性
定义也不同,因为两者都适用于浮点值,但不适用于具有 real 值(如 1/7、√2、π)的量子。 @Eric Postpischil
两个 OP 函数在某些情况下都是错误的。
x
per John Harrison,当 ulp()
是 2 的幂、零或次正态时是错误的。
替代
x
当 #include <math.h>
// Using the convention ULP(x) == ULP(-x)
// Adjust if you want a signed result.
double ulp_JH(double x) {
x = fabs(x);
if (isfinite(x)) {
double lower = nextafter(x,-1.0); // 1st FP number smaller than x
return x - lower;
}
return x; // NAN,infinity
}
为零或次正常时,OP 的 quantum()
有问题。
x
1 除了 double quantum_alt(double x) {
x = fabs(x);
if (x < DBL_MAX) {
double higher = nextafter(x,DBL_MAX); // 1st FP number larger than x
return higher - x;
}
if (isfinite(x)) {
double lower = nextafter(x,0.0); // Special case for DBL_MAX
return x - lower;
}
return x; // NAN,infinity
}
。在这种情况下。 x == DBL_TRUE_MIN
是 ULP(DBL_TRUE_MIN)
。