只是为了好玩,因为它非常简单,我编写了一个生成Grafting numbers的短程序,但是由于浮点精度问题,它找不到一些更大的示例。
def isGrafting(a):
for i in xrange(1, int(ceil(log10(a))) + 2):
if a == floor((sqrt(a) * 10**(i-1)) % 10**int(ceil(log10(a)))):
return 1
a = 0
while(1):
if (isGrafting(a)):
print "%d %.15f" % (a, sqrt(a))
a += 1
此代码至少遗漏了一个已知的嫁接数。9999999998 => 99999.99998999999999949999999994999999999374999999912...
乘以10**5
后,它似乎会降低额外的精度。
>>> a = 9999999998
>>> sqrt(a)
99999.99999
>>> a == floor((sqrt(a) * 10**(5)) % 10**int(ceil(log10(a))))
False
>>> floor((sqrt(a) * 10**(5)) % 10**int(ceil(log10(a))))
9999999999.0
>>> print "%.15f" % sqrt(a)
99999.999989999996615
>>> print "%.15f" % (sqrt(a) * 10**5)
9999999999.000000000000000
<>我写了一个简短的C++程序,看看是不是我的CPU以某种方式截断了浮点号或Python。#include <cstdio>
#include <cmath>
#include <stdint.h>
int main()
{
uint64_t a = 9999999998;
printf("%ld %.15f %.15f %.15f %.15f\n", a, sqrt((double)a), sqrt((double)a)*1e4, sqrt((double)a)*1e5, sqrt((double)a)*1e6);
a = 999999999998;
printf("%ld %.15f %.15f %.15f %.15f\n", a, sqrt((double)a), sqrt((double)a)*1e5, sqrt((double)a)*1e6, sqrt((double)a)*1e7);
a = 99999999999998;
printf("%ld %.15f %.15f %.15f %.15f\n", a, sqrt((double)a), sqrt((double)a)*1e6, sqrt((double)a)*1e7, sqrt((double)a)*1e8);
return 0;
}
哪些输出:
9999999998 99999.999989999996615 999999999.899999976158142 9999999999.000000000000000 99999999990.000000000000000
999999999998 999999.999998999992386 99999999999.899993896484375 999999999999.000000000000000 9999999999990.000000000000000
99999999999998 9999999.999999899417162 9999999999999.900390625000000 99999999999999.000000000000000 999999999999990.000000000000000
所以看起来我在努力克服浮点精度的限制,CPU正在切断剩余的位,因为它认为剩余的差异是浮点错误。在Python下有办法解决这个问题吗?或者我需要转到C并使用GMP或其他什么?
您可以尝试使用Decimal而不是floatingpoint。
对于这个特殊的问题,
decimal
是一个很好的方法,因为它将十进制数字存储为元组!因为您正在寻找一个最自然地用十进制表示法表示的属性,所以使用二进制表示法有点傻。你链接到的维基百科页面没有指明在“嫁接数字”开始之前可能出现多少个“非嫁接数字”,因此可以指定:
我认为
Decimal.sqrt()
的结果很有可能比math.sqrt()
的结果更准确,至少在这方面,因为二进制表示和十进制表示之间的转换。例如,请考虑以下内容:在标准库中,^{} 模块可能是您要查找的。另外,我发现mpmath非常有用。documentation也有许多很好的示例(不幸的是,我的办公计算机没有安装
mpmath
;否则我将验证几个示例并发布它们)。不过,有一条关于^{} 模块的警告。该模块包含几个用于简单数学运算的内置函数(例如
sqrt
),但这些函数的结果可能并不总是与math
或其他精度较高的模块中的相应函数匹配(尽管它们可能更精确)。例如在Python3.2.3中,这将输出前两行
如前所述,这并不是你所期望的那样,你可以看到精度越高,匹配的结果就越少。注意,
decimal
模块在本例中确实具有更高的准确性,因为它与actual value更接近。相关问题 更多 >
编程相关推荐