为什么log(1000)/ log(10)与log10(1000)不同?
今天,我遇到了一个很奇怪的问题。我需要计算数字的字符串长度,所以我想出了这个解决方案
// say the number is 1000(int)(log(1000)/log(10)) + 1
这是基于数学公式
log
10 x = log
n
x/log
n10
(在这里解释)
但是我发现在C语言中
(int)(log(1000)/log(10)) + 1
是 等于
(int) log10(1000) + 1
但应该如此。
我什至用这段代码在Java中尝试了同样的事情
(int) (Math.log(1000) / Math.log(10)) + 1(int) Math.log10(1000) + 1
但它的行为方式相同。
故事还在继续。执行此代码后
for (int i = 10; i < 10000000; i *= 10) { System.out.println(((int) (Math.log10(i)) + 1) +
" " + ((int) (Math.log(i) / Math.log(10)) + 1));
}
我懂了
2 23 3
4 3 // here second method produces wrong result for 1000
5 5
6 6
7 6 // here again
因此,该错误似乎发生在每1000个倍数上。
我向我的C老师展示了这一点,他说这可能是由于日志分割期间的某些类型转换错误引起的,但是他不知道为什么。
所以我的问题是
这不是舍入错误,因为
Math.floor(Math.log10(i)) + 1Math.floor(Math.log(i) / Math.log(10)) + 1
产生相同的错误输出
2 23 3
4 3
5 5
6 6
7 6
我必须四舍五入,因为我想知道 。
log10(999) + 1 = 3.9995654882259823log10(1000) + 1 = 4.0
如果我只是四舍五入,我会得到相同的结果(4),这对于999是错误的,因为它有3位数字。
回答:
您提供了代码段
for (int i = 10; i < 10000000; i *= 10) { System.out.println(((int) (Math.log10(i)) + 1) +
" " + ((int) (Math.log(i) / Math.log(10)) + 1));
}
来说明你的问题。只需删除强制转换,int
然后再次运行循环即可。您将收到
2.0 2.03.0 3.0
4.0 3.9999999999999996
5.0 5.0
6.0 6.0
7.0 6.999999999999999
可以立即回答您的问题。正如tliff所说,强制转换会舍去小数而不是正确舍入。
您更新到使用你的问题floor()
,但像铸造floor()
将全面 下降 ,因此下降的小数!
以上是 为什么log(1000)/ log(10)与log10(1000)不同? 的全部内容, 来源链接: utcz.com/qa/416445.html