当前位置: 首页 > 面试题库 >

为什么log(1000)/ log(10)与log10(1000)不同?

金阳曜
2023-03-14
问题内容

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

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

这是基于数学公式

log10 x = logn
x/logn10(在这里解释)

但是我发现在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位数字。


问题答案:

您提供了代码段

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.0
3.0 3.0
4.0 3.9999999999999996
5.0 5.0
6.0 6.0
7.0 6.999999999999999

可以立即回答您的问题。正如tliff所说,强制转换会舍去小数而不是正确舍入。

编辑: 您更新到使用你的问题floor(),但像铸造floor()将全面 下降 ,因此下降的小数!



 类似资料:
  • 问题内容: 为什么用Java将24 * 60 * 60 * 1000 * 1000除以24 * 60 * 60 * 1000不等于1000? 问题答案: 因为乘法会溢出32位整数。64位还可以: 显然,在乘法溢出之后,除法不会“撤消”该溢出。

  • 在Python3中,行是如何在不到一秒钟的时间内执行的,尽管它应该处理很多项?

  • Log

    xweb默认使用github.com/go-xweb/log来作为log组件,默认输出到屏幕上,如果希望输出到文件,可以自定义log,比如: f, err := os.Create("server.log") if err != nil { println(err.Error()) return } logger := log.New(f, "",

  • log

    fis. log fis 日志输出模块。 Source: log.js, line 2 Members (static) alert 配置是否需要输出命令行警告音。 Source: log.js, line 70 (static) L_ALL [级别] 全部输出 Source: log.js, line 10 (static) L_DEBUG [级别] 输出 debug 信息 Source: lo

  • log

    描述 (Description) 此函数返回EXPR的自然对数,如果省略则返回$ _。 要获取另一个基数的日志,请使用基本代数:数字的base-N日志等于该数字的自然对数除以N的自然对数。 语法 (Syntax) 以下是此函数的简单语法 - log EXPR log 返回值 (Return Value) 此函数在标量上下文中返回浮点数。 例子 (Example) 以下是显示其基本用法的示例代码

  • log

    log(计算以e 为底的对数值) 相关函数 exp,log10,pow 表头文件 #include <math.h> 定义函数 double log (double x); 函数说明 log()用来计算以e为底的x 对数值,然后将结果返回。 返回值 返回参数x的自然对数值。 错误代码 EDOM 参数x为负数,ERANGE 参数x为零值,零的对数值无定义。 附加说明 使用GCC编译时请加入-lm。