Floating point IEEE浮点错误会让我错过素数搜索中的一个因素吗?
在简单的素性检查中,常见的做法是检查从2到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是被测试的数字。如果必须计算平方根,请编写只使用整数算术的函数;牛
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)
最近的可表示双精度也必须是