如何求一个整数的数字长度?
在Python中,如何找到整数的位数?
In Python, how do you find the number of digits in an integer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在Python中,如何找到整数的位数?
In Python, how do you find the number of digits in an integer?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
自从提出这个问题以来已经有好几年了,但我已经编制了几种计算整数长度的方法的基准。
(libc 函数需要一些设置,我没有包括在内)
size_exp
感谢 Brian Preslopsky,size_str
感谢 GeekTantra,以及size_math
> 感谢 John La Rooy以下是结果:(
免责声明:该函数在输入 1 到 1,000,000 上运行)
以下是
sys.maxsize - 100000
到sys.maxsize< 的结果/code>:
如您所见,
mod_size
(len("%i" % i)
) 是最快的,比使用str(i) 稍快一些
并且比其他人快得多。It's been several years since this question was asked, but I have compiled a benchmark of several methods to calculate the length of an integer.
(the libc function requires some setup, which I haven't included)
size_exp
is thanks to Brian Preslopsky,size_str
is thanks to GeekTantra, andsize_math
is thanks to John La RooyHere are the results:
(Disclaimer: the function is run on inputs 1 to 1,000,000)
Here are the results for
sys.maxsize - 100000
tosys.maxsize
:As you can see,
mod_size
(len("%i" % i)
) is the fastest, slightly faster than usingstr(i)
and significantly faster than others.Python
2.*
int
占用 4 或 8 个字节(32 或 64 位),具体取决于您的 Python 版本。sys.maxint
(2**31-1
对于 32 位整数,2**63-1
对于 64 位整数)将告诉你这两种可能性中的哪一种。在 Python 3 中,
int
(如 Python 2 中的long
)可以采用任意大小,最高可达可用内存量;sys.getsizeof
为您提供了任何给定值的良好指示,尽管它确实也计算了一些固定开销:如果,如其他答案所示,您正在考虑某个字符串整数值的表示形式,然后只需取该表示形式的
len
即可,无论是以 10 为基数还是以其他方式!Python
2.*
int
s take either 4 or 8 bytes (32 or 64 bits), depending on your Python build.sys.maxint
(2**31-1
for 32-bit ints,2**63-1
for 64-bit ints) will tell you which of the two possibilities obtains.In Python 3,
int
s (likelong
s in Python 2) can take arbitrary sizes up to the amount of available memory;sys.getsizeof
gives you a good indication for any given value, although it does also count some fixed overhead:If, as other answers suggests, you're thinking about some string representation of the integer value, then just take the
len
of that representation, be it in base 10 or otherwise!令数字为
n
,则n
中的位数由下式给出:请注意,这将为+ve 整数
给出正确答案。 10e15。除此之外,
math.log10
返回类型的精度限制开始生效,答案可能会偏离 1。我会简单地使用len(str(n))
那;这需要O(log(n))
时间,与迭代 10 的幂相同。感谢 @SetiVolkylany 让我注意到这个限制。令人惊讶的是,看似正确的解决方案在实施细节中却有警告。
Let the number be
n
then the number of digits inn
is given by:Note that this will give correct answers for +ve integers < 10e15. Beyond that the precision limits of the return type of
math.log10
kicks in and the answer may be off by 1. I would simply uselen(str(n))
beyond that; this requiresO(log(n))
time which is same as iterating over powers of 10.Thanks to @SetiVolkylany for bringing my attenstion to this limitation. Its amazing how seemingly correct solutions have caveats in implementation details.
好吧,如果不转换为字符串,我会做类似的事情:
Minimalist recursion FTW
Well, without converting to string I would do something like:
Minimalist recursion FTW
正如亲爱的用户 @Calvintwr 所提到的,函数 math.log10 在数字超出范围 [-999999999999997, 999999999999997] 时出现问题,我们会遇到浮点错误。我在 JavaScript(Google V8 和 NodeJS)和 C(GNU GCC 编译器)中遇到了这个问题,因此这里不可能使用“纯数学”解决方案。
基于此要点和回答亲爱的用户@Calvintwr
我在长度最大为20(含)的数字上进行了测试,没问题。它必须足够了,因为 64 位系统上的最大长度整数是 19 (
len(str(sys.maxsize)) == 19
)。所有代码示例均使用 Python 3.5 进行测试
As mentioned the dear user @Calvintwr, the function
math.log10
has problem in a number outside of a range [-999999999999997, 999999999999997], where we get floating point errors. I had this problem with the JavaScript (the Google V8 and the NodeJS) and the C (the GNU GCC compiler), so a'purely mathematically'
solution is impossible here.Based on this gist and the answer the dear user @Calvintwr
I tested it on numbers with length up to 20 (inclusive) and all right. It must be enough, because the length max integer number on a 64-bit system is 19 (
len(str(sys.maxsize)) == 19
).All example of codes tested with the Python 3.5
计算不将整数转换为字符串的位数:
Count the number of digits w/o convert integer to a string:
这是一个庞大但快速的版本:
对于不太大的数字只有 5 次比较。
在我的计算机上,它比
math.log10
版本快约 30%,比len( str()) 版本快 5%。
好吧……如果你不疯狂地使用它的话,不会那么有吸引力。
这是我用来测试/测量我的功能的一组数字:
注意:它不管理负数,但适应很容易......
Here is a bulky but fast version :
Only 5 comparisons for not too big numbers.
On my computer it is about 30% faster than the
math.log10
version and 5% faster than thelen( str())
one.Ok... no so attractive if you don't use it furiously.
And here is the set of numbers I used to test/measure my function:
NB: it does not manage negative numbers, but the adaptation is easy...
如其他答案所示,在使用
len(str(...))
或手动循环时,使用log10
会导致大n
的错误结果导致较大n
的性能下降。 Jodag 的答案提供了一个非常好的替代方案,它只对可能导致计算机崩溃的整数失败,但我们可以做得更好甚至更快(对于n
足够小,保证math.log2
准确),完全避免对数并使用二进制代替:让我们分解一下。首先,有奇怪的
n.bit_length()
。这以二进制计算长度:与对数不同,这对于整数来说既快速又精确。事实证明,这恰好产生
floor(log2(n)) + 1
。为了获得floor(log2(n))
本身,我们减去1
,因此得到n.bit_length() - 1
。接下来,我们乘以
0.30102999566398114
。这相当于稍微向下舍入的log10(2)
。这利用对数规则来根据floor(log2(n))
计算floor(log10(n))
的估计值。现在,您可能想知道此时我们的情况如何,因为虽然
0.30102999566398114 * log2(n) ~ log10(n)
,但floor(0.30102999566398114 * Floor 则不然) (log2(n))) ~ 楼层(log10(n))
。回想一下 x - 1Floor(x) <= x
这样我们就可以做一些快速的数学计算:请注意,
floor(log10(n) - 0.30102999566398114)
至少是floor(log10( n)) - 1
,这意味着我们与结果最多相差1
。这是最终修正的地方,我们检查10 ** i <= n
,当结果太小或 < code>0 + 时结果正好。与 Jodag 的答案类似,这种方法实际上对于非常非常大的
n
失败,大约在10 ** 2 ** 52
处,其中i
关闭超过-1
。但是,该大小的整数可能会使您的计算机崩溃,因此这应该足够了。As shown by other answers, using
log10
leads to incorrect results for largen
while usinglen(str(...))
or manual looping leads to slow performance for largen
. Jodag's answer provides a really good alternative which only fails for integers that will likely crash your computer, but we can do a bit better and even faster (forn
small enough thatmath.log2
is guaranteed to be accurate) by avoid logarithms altogether and using binary instead:Let's break this down. First, there's the weird
n.bit_length()
. This calculates the length in binary:Unlike logarithms, this is both fast and precise for integers. As it turns out, this results in exactly
floor(log2(n)) + 1
. In order to get thefloor(log2(n))
on its own, we subtract1
, hence then.bit_length() - 1
.Next, we multiply by
0.30102999566398114
. This is equivalent tolog10(2)
slightly rounded down. This takes advantage of logarithmic rules in order to calculate an estimate offloor(log10(n))
fromfloor(log2(n))
.Now, you might be wondering how off we might be at this point, because although
0.30102999566398114 * log2(n) ~ log10(n)
, the same is not true forfloor(0.30102999566398114 * floor(log2(n))) ~ floor(log10(n))
. Recall thatx - 1 < floor(x) <= x
so that we can do some quick math:Note then that
floor(log10(n) - 0.30102999566398114)
is at leastfloor(log10(n)) - 1
, meaning we are at most1
off from our result. This is where the final correction comes in, where we check10 ** i <= n
, which results in an extra1 +
when the result is too small or0 +
when the result is just right.Similar to Jodag's answer, this approach actually fails for very very large
n
, somewhere around10 ** 2 ** 52
wherei
is off by more than-1
. However, integers of that size will likely crash your computer, so this should suffice.对于后人来说,毫无疑问是迄今为止解决这个问题最慢的方法:
For posterity, no doubt by far the slowest solution to this problem:
一种快速解决方案,基于“更好的方法”使用
floor(log10(n))
的自我纠正实现计算整数 n 和 b 的 log(n,b) 下限?”。这非常快,并且只要
n
n
n
n
n
n
n
n
n
n
n
10**(2**52)
(这真的很大)。A fast solution that uses a self-correcting implementation of
floor(log10(n))
based on "Better way to compute floor of log(n,b) for integers n and b?".This is quite fast and will work whenever
n < 10**(2**52)
(which is really really big).假设您要求以整数形式存储的最大数字,则该值取决于实现。我建议大家在使用python的时候不要这样想。无论如何,Python 的“整数”中可以存储相当大的值。请记住,Python 使用鸭子类型!
编辑:
我在澄清提问者想要位数之前就给出了答案。为此,我同意已接受答案建议的方法。没什么可补充的了!
Assuming you are asking for the largest number you can store in an integer, the value is implementation dependent. I suggest that you don't think in that way when using python. In any case, quite a large value can be stored in a python 'integer'. Remember, Python uses duck typing!
Edit:
I gave my answer before the clarification that the asker wanted the number of digits. For that, I agree with the method suggested by the accepted answer. Nothing more to add!
对于整数,可以使用以下方法快速完成:
获取“1234567890”绝对值的字符串长度
abs
返回没有任何负数的数字(仅数字的大小),str
将其转换/转换为字符串,len
返回该字符串的字符串长度。如果您希望它适用于浮点数,您可以使用以下任一选项:
供将来参考。
It can be done for integers quickly by using:
Which gets the length of the string of the absolute value of "1234567890"
abs
returns the number WITHOUT any negatives (only the magnitude of the number),str
casts/converts it to a string andlen
returns the string length of that string.If you want it to work for floats, you can use either of the following:
For future reference.
用科学记数法格式化并去掉指数:
我不知道速度,但很简单。
请注意小数点后的有效位数(如果将科学记数法的小数部分四舍五入到另一个数字,“.5e”中的“5”可能会出现问题。我将其设置为任意大,但可以反映您所知道的最大数字的长度。
Format in scientific notation and pluck off the exponent:
I don't know about speed, but it's simple.
Please note the number of significant digits after the decimal (the "5" in the ".5e" can be an issue if it rounds up the decimal part of the scientific notation to another digit. I set it arbitrarily large, but could reflect the length of the largest number you know about.
这是另一种计算任何数字小数点前位数的方法,
我做了一个简短的基准测试,针对 10,000 个循环,
它速度较慢,但是一个更简单的选择。
但即使这个解决方案确实给出了错误的结果 9999999999999998
Here is another way to compute the number of digit before the decimal of any number
I did a brief benchmark test, for 10,000 loops
It is slower but a simpler option.
But even this solution does give wrong results from 9999999999999998
我的代码如下;我使用了 log10 方法:
def digital_count(number):
我必须指定 1 和 0 的情况,因为 log10(1)=0 和 log10(0)=ND ,因此条件提到的不满意。但是,此代码仅适用于整数。
My code for the same is as follows;i have used the log10 method:
def digit_count(number):
I had to specify in case of 1 and 0 because log10(1)=0 and log10(0)=ND and hence the condition mentioned isn't satisfied. However, this code works only for whole numbers.
最常见的答案是 mathlog10 更快,但我得到的结果表明 len(str(n)) 更快。
此外,我还没有在数学方法中添加逻辑来返回准确的结果,我只能想象它会进一步减慢速度。
我不知道以前的答案如何证明数学方法更快。
Top answers are saying mathlog10 faster but I got results that suggest len(str(n)) is faster.
Besides, I haven't added logic to the math way to return accurate results and I can only imagine it slows it even more.
I have no idea how the previous answers proved the maths way is faster though.
输出:数字的位数为:16
output: The number of digits in the number are: 16
如果您正在寻找不使用内置函数的解决方案。
唯一需要注意的是当您发送
a = 000
时。If you are looking for a solution without using inbuilt functions.
Only caveat is when you send
a = 000
.这是最简单的方法,无需将 int 转换为字符串:
假设给出 15 位数字,例如; n=787878899999999;
输入:
输出:
Here is the simplest approach without need to be convert int into the string:
suppose a number of 15 digits is given eg; n=787878899999999;
Input :
Output:
如果您必须要求用户提供输入,然后您必须计算有多少个数字,那么您可以按照以下步骤操作:
注意:切勿将 int 作为用户输入。
If you have to ask an user to give input and then you have to count how many numbers are there then you can follow this:
Note: Never take an int as user input.
没有导入和 str() 等函数的解决方案
Solution without imports and functions like str()
您可以使用此解决方案:
You can use this solution:
让我们看几个例子:
#Example 1,在这种情况下效果很好
#Example 2,需要将负整数设为正数才能使该函数工作
#Example 3,整数前的零不是函数可以理解,因此在我们输入函数之前需要注意它
Let's see a few examples:
#Example 1, it will work fine for this case
#Example 2, negative integer number need to be made positive to this function to work
#Example 3, zero before integer is not understood by the function so it needs to be taken care before we feed into the function
如果您想要整数的长度作为整数中的位数,您始终可以将其转换为字符串,如
str(133)
并找到其长度,如len(str(123 ))
。If you want the length of an integer as in the number of digits in the integer, you can always convert it to string like
str(133)
and find its length likelen(str(123))
.无需转换为字符串
也可以处理零和负数
您可能希望将其放入函数中:)
这里有一些基准。即使对于很小的数字,
len(str())
也已经落后了Without conversion to string
To also handle zero and negative numbers
You'd probably want to put that in a function :)
Here are some benchmarks. The
len(str())
is already behind for even quite small numbers所有 math.log10 解决方案都会给您带来问题。
math.log10 速度很快,但当您的数字大于 999999999999997 时会出现问题。这是因为浮点数有太多 .9,导致结果向上舍入。
因此,为了获得最佳性能,请对较小的数字使用
math.log
,并且仅使用len(str())
超出math.log
的范围处理:All math.log10 solutions will give you problems.
math.log10 is fast but gives problem when your number is greater than 999999999999997. This is because the float have too many .9s, causing the result to round up.
Therefore, to get the best performance, use
math.log
for smaller numbers and onlylen(str())
beyond whatmath.log
can handle: