我该如何实现?
// round to the nearest double so that x + ref doesn't cause round off error
double round(double x, double ref) { }
那样
double x = ....;
double y = ....;
double x_new = round(x, y);
return x_new + y; // NO ROUND OFF!
换句话说(y + x_new) - x_new严格等于y
答案 0 :(得分:2)
我们假设x
和y
都是正面的。
让S
为双精度和x + y
。
有两种情况:
如果x
≤y
,则S - y
完全符合Sterbenz的引理。因此,加法(S - y) + y
是精确的(它精确地生成S
,这是一个双精度数)。因此,您可以为S - y
选择x_new
。 y + x_new
不仅精确,而且与S
产生的结果相同y + x
。
如果x
> y
,然后根据y
有效位数中设置的位数,您可能会遇到问题。例如,如果设置了y
的有效位数中的最后一位,那么在z
的二分之后,binade中的数字y
可以具有z + y
的属性精确。
这个答案与that answer含糊不清。
答案 1 :(得分:0)
Python中可能直接转换为C
的可能解决方案import math
from decimal import Decimal
def round2(x, ref):
x_n, x_exp = math.frexp(x)
ref_n, ref_exp = math.frexp(ref)
assert x_exp <= ref_exp
diff_exp = ref_exp - x_exp
factor = 2. ** (53 - diff_exp)
x_new_as_int = int(round(x_n * factor))
x_new_as_norm_float = float(x_new_as_int) / factor
return math.ldexp(x_new_as_norm_float, x_exp)
x = 0.001
y = 1.0
assert (y + x) - x != y
x_new = round2(x, y)
assert (y + x_new) - x_new == y
print "x:", Decimal(x)
print "x_new:", Decimal(x_new)
print "relative difference:", (x_new/x - 1.)