今天,我遇到了一个很奇怪的问题。我需要计算一个数字的字符串长度,所以我想出了这个解决方案
// 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 2
3 3
4 3 // here second method produces wrong result for 1000
5 5
6 6
7 6 // here again
所以这个错误似乎发生在每 1000 的倍数上。
我把这个给我的C老师看,他说可能是对数除法时的类型转换错误,但不知道为什么。
所以我的问题是
- 根据数学,为什么不
(int) (Math.log(1000) / Math.log(10)) + 1
等于(int) Math.log10(1000) + 1
,而应该是。 - 为什么只有 1000 的倍数是错误的?
编辑:这不是舍入误差,因为
Math.floor(Math.log10(i)) + 1
Math.floor(Math.log(i) / Math.log(10)) + 1
产生相同的错误输出
2 2
3 3
4 3
5 5
6 6
7 6
edit2:我必须四舍五入,因为我想知道位数。
log10(999) + 1 = 3.9995654882259823
log10(1000) + 1 = 4.0
如果我只是四舍五入,我会得到相同的结果 (4),这对于 999 是错误的,因为它有 3 位数字。