“我的”怎么了;“数字查找器”;用python?

“我的”怎么了;“数字查找器”;用python?,python,Python,我正在通过Euler问题项目学习python。因为我写了以下代码: import math i = 1 counter = 0 while counter <= 1000000: MMM = int(math.log(i, 10)) + 1 counter = counter + MMM V = math.log(i, 10) print(i, counter, MMM, V) i += 1 与 像冠军一样工作 虽然有一个全数字的解决方案会很好,但

我正在通过Euler问题项目学习python。因为我写了以下代码:

import math
i = 1
counter = 0
while counter <= 1000000:
    MMM = int(math.log(i, 10)) + 1
    counter = counter + MMM
    V = math.log(i, 10)
    print(i, counter, MMM, V)
    i += 1

像冠军一样工作


虽然有一个全数字的解决方案会很好,但它必须等到我可以信任Python中的日志函数时才可以使用。

浮点错误?可能在某个时刻,
math.log
返回的值刚好小于(或大于,取决于off-by-1结果的方向)整数边界,因此,
int()
将其截断为错误的值。对于不能用一定数量的二进制数字表示的数字,浮点数是不精确的。

我认为这就是问题所在

MMM = int(math.log(i, 10)) + 1
一些例子

>>> int(math.log(1000000, 10)) + 1
6
>>> int(math.log(1000001, 10)) + 1
7
而我怀疑你真的想要

>>> len(str(1000000))
7
>>> len(str(1000001))
7
编辑事实上(正如您所建议的!)math.log10似乎是最好的解决方案,与您最初编写的内容更加一致

>>> int(math.log10(10000000))
7
>>> int(math.log10(10000001))
7
>>> int(math.log10(10**1000))
1000
>>> int(math.log10(10**10000))
10000
>>> int(math.log10(10**100000))
100000

math.log10
必须保持比
math.log(x,10)
更高的精度这里的问题是浮点数的精度,这并不令人惊讶。随着位数的增加,我变得越来越模糊。这是浮点数的基本性质,当你做这种数学时,你需要知道你需要什么样的精度

标准库模块允许您对十进制值的精度进行细粒度控制。由于此模块不是硬件基础,因此用户可以更改浮点数的精度(默认为28位)。您可以创建如下所示的十进制数:

 import decimal
 x = decimal.Decimal(1000000)
 x.log10()

您可以这样更改所需的精度:
decimal.getcontext().prec=8

大,大,大提示:不要将其视为小数,将其视为字符串。我很快就发现必须使用字符串来完成,但是在编译了一个足够长的字符串来包含1000000个数字之后,我想应该有一种方法来“计算”哪个附加的数字有哪个数字,并对它进行索引,以便知道哪些数字实际上由附加的数字表示。我写的代码实际上就是这样做的,计数器的值给出了所附加数字中最后一个数字的数字。然而,某处出现故障,计数器一个接一个关闭。我想知道这是为什么,什么时候发生的。只是想澄清一下我的数学背后发生了什么。任何数字的公共日志的整数部分是位数减1。(据我所知…)因此,如果我将一个数字添加到连续数字的公共日志中,并跟踪这些值,以保持运行总数,则当总数计数器大于N时,第N个数字应包含在附加的数字中。例如:当附加数字366时,有987个数字,所以它包含第988位、第989位和第990位。当按顺序循环时,log可能太重且不精确,无法跟踪数字的数量。可能有更精确的方法只使用整数算术:(模,)加法和乘法。这似乎是合理的。因为随着位数的增加,math.log的值将越来越接近整数值。换句话说,log(999999)的小数部分比log(99)的小数部分多了一个“9”。有什么办法可以解决这个问题吗?或者说,不管用这种方法做什么,我都要听命于浮点的本性吗?@Jim:我认为你是对的,在极端情况下,使用
log
会使你面临浮点不准确的问题。当然,这是一种独特的解决方法。除了我在下面的评论之外,我还不知道len()函数以这种方式处理字符串。我的印象是它只会计算元素,即len(str(100000))是1而不是6。从现在起我会记住这一点。它确实只计算元素,但字符串实际上是字符列表。要得到1的结果,必须对字符串列表进行计数:len([str(100000)])
>>> int(math.log10(10000000))
7
>>> int(math.log10(10000001))
7
>>> int(math.log10(10**1000))
1000
>>> int(math.log10(10**10000))
10000
>>> int(math.log10(10**100000))
100000
 import decimal
 x = decimal.Decimal(1000000)
 x.log10()