【发布时间】:2011-06-24 09:04:36
【问题描述】:
我正在尝试确定 c# ulong 数字中的位数,我正在尝试使用一些数学逻辑而不是使用 ToString().Length。我没有对这两种方法进行基准测试,但看过其他关于使用 System.Math.Floor(System.Math.Log10(number)) + 1 来确定位数的帖子。 似乎工作正常,直到我从 999999999999997 过渡到 999999999999998 时,我开始得到不正确的计数。
以前有人遇到过这个问题吗?
我看过类似的帖子,强调 Java 的 @Why log(1000)/log(10) isn't the same as log10(1000)? 和 @How to get the separate digits of an int number? 的帖子表明我如何使用 % 运算符实现相同的目标,但代码更多
这是我用来模拟的代码
Action<ulong> displayInfo = number =>
Console.WriteLine("{0,-20} {1,-20} {2,-20} {3,-20} {4,-20}",
number,
number.ToString().Length,
System.Math.Log10(number),
System.Math.Floor(System.Math.Log10(number)),
System.Math.Floor(System.Math.Log10(number)) + 1);
Array.ForEach(new ulong[] {
9U,
99U,
999U,
9999U,
99999U,
999999U,
9999999U,
99999999U,
999999999U,
9999999999U,
99999999999U,
999999999999U,
9999999999999U,
99999999999999U,
999999999999999U,
9999999999999999U,
99999999999999999U,
999999999999999999U,
9999999999999999999U}, displayInfo);
Array.ForEach(new ulong[] {
1U,
19U,
199U,
1999U,
19999U,
199999U,
1999999U,
19999999U,
199999999U,
1999999999U,
19999999999U,
199999999999U,
1999999999999U,
19999999999999U,
199999999999999U,
1999999999999999U,
19999999999999999U,
199999999999999999U,
1999999999999999999U
}, displayInfo);
提前致谢
拍拍
【问题讨论】:
-
你不需要
%运算符,整数除法就够了。 “更多代码”是一个单语句循环。没有那么多代码。 -
ToString().Length 真的那么贵吗?也许它的头发慢一些,但它对于任何值都是准确的。对我来说,准确性比效率更重要。
-
使用
Log10函数时开始得到错误结果是有道理的,因为该函数使用double类型,它不能准确表示非常大的整数(参见en.wikipedia.org/wiki/Double_precision_floating-point_format)跨度> -
我同意,我认为使用
ToString().Length没有什么特别的问题。此外,您可以将Action更改为常规方法,只要签名正确即可。 -
请看stackoverflow.com/questions/4143000/…——如果你想要“速度”,请看“级联if”版本(可以分成几个部分,类似于迭代方法)。否则这里可能只是
ToString。if可以移动到 List 的快速迭代中。