为什么log(1000)/ log(10)与log10(1000)不同? [英] Why log(1000)/log(10) isn't the same as log10(1000)?

查看:316
本文介绍了为什么log(1000)/ log(10)与log10(1000)不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我遇到了一个非常奇怪的问题。我需要计算一个数字的字符串长度,所以我想出了这个解决方案

Today, I came across quite strange problem. I needed to calculate string length of a number, so I came up with this solution

// say the number is 1000
(int)(log(1000)/log(10)) + 1

这是基于数学公式

log 10 x = log <子>名词 X /日志 <子>名词 10 (解释此处

log10x = lognx/logn10 (explained here)

但我发现,在C中,

(int)(log(1000)/log(10)) + 1

等于

(int) log10(1000) + 1

但它应该是。

我甚至在Java中使用此代码尝试了同样的事情

I even tried the same thing in Java with this code

(int) (Math.log(1000) / Math.log(10)) + 1
(int) Math.log10(1000) + 1

但它的行为方式相同。

故事仍在继续。执行此代码后

The story continues. After executing this code

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的倍数上。

So the bug seems to occur on every multiple of 1000.

我向我的C老师展示了这个,他说这可能是由于日志分割期间的某种类型转换错误造成的,但他不知道原因。

I showed this to my C teacher, and he said that it might be caused by some type conversion error during log division, but he didn't know why.

所以我的问题是


  • 为什么不是( int)(Math.log(1000)/ Math.log(10))+ 1 等于(int)Math.log10(1000)+ 1
    ,虽然它应该是,但根据数学。

  • 为什么只有1000的倍数出错?

  • Why isn't (int) (Math.log(1000) / Math.log(10)) + 1 equal to (int) Math.log10(1000) + 1 , while it should be, according to the math.
  • Why is it wrong only for multiples of 1000?

编辑:这不是舍入错误,因为

edit: It is not rounding error, because

Math.floor(Math.log10(i)) + 1
Math.floor(Math.log(i) / Math.log(10)) + 1

produc同样,输出错误

produce same, wrong output

2 2
3 3
4 3
5 5
6 6
7 6

edit2: I必须向下舍入,因为我想知道位数

edit2: I have to round down, because I want to know the number of digits.

log10(999) + 1 = 3.9995654882259823
log10(1000) + 1 =  4.0

如果我只是圆形,我得到相同的结果(4),这对999是错误的,因为它有3位数。

If I just round, I get same result (4), which is wrong for 999, because it has 3 digits.

推荐答案

你提供了代码片段

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 并再次运行循环。您将收到

to illustrate your question. Just remove the casts to int and run the loop again. You will receive

2.0 2.0
3.0 3.0
4.0 3.9999999999999996
5.0 5.0
6.0 6.0
7.0 6.999999999999999

可立即回答您的问题。正如tliff已经提出的那样,演员们会截取小数而不是正确地舍入。

which immediately answers your question. As tliff already argued, the casts cut off the decimals instead of rounding properly.

编辑:您更新了问题以使用 floor(),但是像投射 floor()将围绕向下,因此删除小数!

You updated your question to use floor(), but like casting floor() will round down and therefore drop the decimals!

这篇关于为什么log(1000)/ log(10)与log10(1000)不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆