这个问题与 (b - a) + a != b 何时恰好在浮点中 但带有一个附加乘法器
c
必须严格小于 1
。
正式地,我问自己是否存在任何浮点数
a
、b
和c
使得
0 <= a < b
0 <= c < 1
a + (b - a) * c > b
.如果存在这样的三元组,我进一步想知道我们是否可以找到正常的浮点数,或者这三个数中的某些是否需要次正规。
首先要找到这样的三元组,很明显,如果它有效,它将与
c = 1. - epsilon
一起工作,即小于1
的最大浮点。因此,为了找到 a
和 b
的合适值,我尝试了多种方法但没有成功:
a = i / n
和b = j / n
与0 <= i < j <= n
对:https://stackoverflow.com/a/51383057/23137796。我尝试了所有 (i,j,n)
与 n <= 1000
的配对。我可以找到很多带有 a + (b - a) > b
的配对,但没有找到带有 a + (b - a) * c > b
的配对。a
和 b
值(即彼此仅相距 epsilon 或相距某个常数倍的 epsilon,最多 100)。我找不到任何一对满足a + (b - a) > b
。考虑 IEEE-754 二进制 32 向 + 无穷大舍入。令
a
为 ½−2−25,即 1/2 以下的可表示数。令 b
为 1。令 c
为 1−2−24,即小于 1 的可表示数字。b
−a
(数学减法)为 ½+2−25。这是不可表示的,因此 b-a
(浮点减法)向 +∞ 舍入会产生 ½+2−24。 b-a
•c
是 ½+2−24−2−25-2−48,因此 (b-a)*c
产生 ½+2−24。那么 a
+(b-a)*c
就是 ½−2−25+½+2−24 = 1−225+2−24 = 1+2−25。 1+2−25 无法表示,因此向 +∞ 舍入会产生 1+2−23,因此 a + (b-a)*c
会产生 1+2−23,它大于 b
。
用 C 语言演示,输出:
#include <fenv.h>
#include <stdio.h>
#include <math.h>
#pragma STDC FENV_ACCESS ON
int main(void)
{
fesetround(FE_UPWARD);
float a = nexttowardf(.5f, 0);
float b = 1;
float c = nexttowardf(1, 0);
printf("%a\n", a + (b-a)*c);
}
是:
0x1.000002p+0