Floating point IEEE浮点错误会让我错过素数搜索中的一个因素吗?

Floating point IEEE浮点错误会让我错过素数搜索中的一个因素吗?,floating-point,primes,Floating Point,Primes,在简单的素性检查中,常见的做法是检查从2到max=floor(sqrt(n))的除数 在IEEE定义的浮点运算(例如32位和64位数字)中,浮点错误是否会使您错过略大于max的因子 例如,max=floor(sqrt(REALLY_BIG_N)),但是(max+1)*something=REALLY_BIG_N 如果我的问题不完全清楚,请评论 (请注意,我对这里的素性检查选项不感兴趣,也不想通过使用x*xn,其中d是试用除数,n是被测试的数字。如果必须计算平方根,请编写只使用整数算术的函数;牛

在简单的素性检查中,常见的做法是检查从2到
max=floor(sqrt(n))
的除数

在IEEE定义的浮点运算(例如32位和64位数字)中,浮点错误是否会使您错过略大于
max
的因子

例如,
max=floor(sqrt(REALLY_BIG_N))
,但是
(max+1)*something=REALLY_BIG_N


如果我的问题不完全清楚,请评论

(请注意,我对这里的素性检查选项不感兴趣,也不想通过使用
x*x
来避免
sqrt
——我的问题实际上是它是否适用于IEEE浮点算法。)

我假设
max+1
可以表示为浮点值(它不会太大,以至于超出了浮点格式可以表示区间中所有整数的区间)

我还假设你的
(max+1)*something
中的
something
是大于
max
的整数。否则,它(或更小的因子)将在之前的除数搜索中找到。这意味着n≤ (最大+1)•(最大+1)

正确实现的
sqrt
返回最接近其参数平方根的可表示值。因此,如果
n
的数学平方根至少为
x+1
,则
sqrt(n)
必须返回
x+1
或更大;它不能返回
x
,因为
x
x+1
离平方根更远。因此,
max=floor(sqrt(n))的结果不小于floor(sqrt(n))的数学值


对于IEEE-754 64位二进制(以下简称为“双精度”
),所有高达253的整数都是可表示的。253+1是第一个不可表示的整数。因此,上面告诉我们,
sqrt(n)
足以满足所有
n
到但不包括(253+1)2的要求。当然,许多大的整数在
double
中并不完全可表示,因此首先不能将它们传递给
sqrt

在处理素数时没有理由使用浮点运算。曾经您不应该计算
max
,而应该循环到
d*d>n
,其中
d
是试用除数,
n
是被测试的数字。如果必须计算平方根,请编写只使用整数算术的函数;牛顿的方法对整数非常有效

编辑:这里有一个计算整数平方根的简单函数:给定一个整数
n
isqrt(n)
返回最大的整数
*x
,其中
x*x
不超过
n
;所有除法都是整数除法,用于截断任何分数余数:

function isqrt(n)
    x := n
    y := (x + n // x) // 2
    while y < x
        x := y
        y := (x + n // x) // 2
    return x
函数isqrt(n)
x:=n
y:=(x+n//x)//2
而y
补充Eric Postpichil的回答:是的,然后又是否。这取决于我们在
n
非常大的情况下如何解释
floor(sqrt(n))

在Eric的回答中,假设IEEE 754 binary64格式浮点和正确舍入的
sqrt
,通常的舍入与偶数舍入模式有效。我还假设访问
n
的任意精度整数类型

第一种解释:假设允许
n
接受任何整数值,并且
floor(sqrt(n))
将被解释为
floor(sqrt(convert_to_double(n))
。然后,
n>=2^1024-2^970
会立即出现问题,因为
convert\u to\u double
会在该点溢出。(我假设
convert_to_double
也是正确的四舍五入。)从另一端开始,Eric的回答已经表明,我们很擅长但不包括
n=(2^53+1)^2
,正如他所建议的,
n=(2^53+1)^2
是一个问题案例:有
convert_to_double(n)
的值
2^106+2^54
,比真实值小一个,
sqrt(convert_to_double(n))
将四舍五入到
2^53
,这意味着您的试算除法函数将错过系数
2^53+1
。然而,考虑到
2^53+1
可以被
3
107
整除,审判庭可能已经发现了其他因素,因此缺少
2^53+1
可能不是问题。在这种情况下,
n=(2^53+5)^2
应被视为第一个问题案例。(
2^53+5
为素数。)


第二种解释:假设
n
被约束为一个正整数,可以用double表示。然后一个整洁的事实是,
n
的任何除数也必须精确地表示为双精度:
n
可以写成
m•2^e
的形式,对于一些非负指数
e
和奇数整数
m
m<2^53
,对于
m
的一些除数
d
0的指数
f
,n
的任何除数都可以写成
d•2^f
的形式,你是说
float
而不是
float
,比如
max=floor(sqrt(REALLY_BIG_n))
!我更新了-谢谢。我认为这比这更容易:如果
n
是一个整数,可以精确表示为IEEE 754二进制双精度,那么很容易看出
n
的所有除数也可以精确表示。现在,对于任何除数
x
,如果n的精确平方根是
=x
,那么与
sqrt(n)
最近的可表示双精度也必须是