IEEE 754:除法之前的转换会导致精度损失吗?
IEEE 754: can casting before division cause loss of precision?
是否存在两个整数 i
和 j
都符合 IEEE 754 双精度(小于 DBL_MAX
),但 to_double(i)/to_double(j)
不符合等于 to_double(i/j)
,这里 i/j
是以无限精度执行的?
(我们可以假设 to_double
是四舍五入,即使这很重要)。
我的问题类似于 ,但我不认为它是等效的,或者至少我不知道如何使用它来获得我的问题的反例。
是的。在 double
是 IEEE-754 基本 64 位二进制 floating-point(具有 53 位有效数)并且 long double
具有 64 位有效数的 C 实现中,输出:
#include <stdio.h>
int main(void)
{
long double x = 0x1p154L - 0x1p101L + 0x1p100L;
long double y = 0x1p153L + 0x1p101L - 0x1p100L;
long double z = x / y;
double X = x;
double Y = y;
double Z = X/Y;
printf("x = %La.\n", x);
printf("y = %La.\n", y);
printf("z = %La.\n", z);
printf("X = %a.\n", X);
printf("Y = %a.\n", Y);
printf("Z = %a.\n", Z);
printf("(double) z = %a.\n", (double) z);
}
是:
x = 0xf.ffffffffffffcp+150.
y = 0x8.0000000000004p+150.
z = 0xf.ffffffffffff4p-3.
X = 0x1p+154.
Y = 0x1p+153.
Z = 0x1p+1.
(double) z = 0x1.ffffffffffffep+0.
x / y
以 long double
精度执行,当然,而不是无限精度,但它捕获了足够的信息来显示无限精度的结果将具有相同的最终结果——插入 #include <math.h>
和 z = nexttowardl(z, INFINITY);
将 (double) z
更改为 0x1.fffffffffffffp+0
,但这仍然不等于 Z
。
是否存在两个整数 i
和 j
都符合 IEEE 754 双精度(小于 DBL_MAX
),但 to_double(i)/to_double(j)
不符合等于 to_double(i/j)
,这里 i/j
是以无限精度执行的?
(我们可以假设 to_double
是四舍五入,即使这很重要)。
我的问题类似于
是的。在 double
是 IEEE-754 基本 64 位二进制 floating-point(具有 53 位有效数)并且 long double
具有 64 位有效数的 C 实现中,输出:
#include <stdio.h>
int main(void)
{
long double x = 0x1p154L - 0x1p101L + 0x1p100L;
long double y = 0x1p153L + 0x1p101L - 0x1p100L;
long double z = x / y;
double X = x;
double Y = y;
double Z = X/Y;
printf("x = %La.\n", x);
printf("y = %La.\n", y);
printf("z = %La.\n", z);
printf("X = %a.\n", X);
printf("Y = %a.\n", Y);
printf("Z = %a.\n", Z);
printf("(double) z = %a.\n", (double) z);
}
是:
x = 0xf.ffffffffffffcp+150. y = 0x8.0000000000004p+150. z = 0xf.ffffffffffff4p-3. X = 0x1p+154. Y = 0x1p+153. Z = 0x1p+1. (double) z = 0x1.ffffffffffffep+0.
x / y
以 long double
精度执行,当然,而不是无限精度,但它捕获了足够的信息来显示无限精度的结果将具有相同的最终结果——插入 #include <math.h>
和 z = nexttowardl(z, INFINITY);
将 (double) z
更改为 0x1.fffffffffffffp+0
,但这仍然不等于 Z
。