ULP(约翰·哈里森的定义)和量子(来自 IEEE 754)有什么区别?
[edit]
OP's quantum()
似乎不正确,始终返回1.11022e-16
对于所有有限的x
,即使当x
是次正常的。
其余答案假设quantum()
更像是quantum_alt()
下面对于每个 [2 的幂 ... 2*2 的幂) 都有相同的结果。请注意[)
.
基数的幂
When x
是基础力量这些定义仅在基数的有符号幂上有所不同 https://en.wikipedia.org/wiki/Unit_in_the_last_place#Definition
For binary64 https://en.wikipedia.org/wiki/Double-precision_floating-point_format,考虑何时x
是 2 的幂。下一个较大的 FP 值是x + u
下一个较小的值是x - u/2
.
John Harrison: "distance between the two closest straddling floating-point numbers a and b (i.e., those with a ≤ x ≤ b and a ≠ b)" implies a
is the smaller value and x == b
and ULP is u/2
.1
量子:“表示是一个单位在其有效数最后位置的值”意味着ULP
is u
.
距离b-a
是“量子”定义的 1/2;a
处于较小的指数子范围内x
并且其最后一个有效位置是一半x
.
适用性
定义也有所不同,两者都适用于浮点值,但不适用于quantum with real https://en.wikipedia.org/wiki/Real_number诸如 1/7、√2、π 等值。@埃里克·波斯特皮斯基尔 https://stackoverflow.com/questions/66637497/difference-between-ulp-unit-in-the-last-place-and-quantum-ieee-754/66640220#comment117800427_66637497
在某些情况下,两个 OP 函数都是错误的。
ulp()
根据约翰·哈里森的说法,当x
是 2 的幂、零或次正规数。
备用
#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's quantum()
当x
是零或次正常值。
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
}
1 Except when x == DBL_TRUE_MIN
. In that case. ULP(DBL_TRUE_MIN)
is DBL_TRUE_MIN
.