【问题标题】:Base 2 custom method and approximation in JavaJava中的Base 2自定义方法和近似值
【发布时间】:2021-08-23 05:44:25
【问题描述】:

我正在编写一个网络计算器的方法,该方法计算需要多少位来提供多个主机。这是给我一些问题的代码:

int hostBits = (int) Math.ceil(Math.log(hosts) / Math.log(2));

它适用于小数字,但当我输入大数字时会出现问题,例如 2^31 - 2,因为Math.log(hosts) / Math.log(2)(更改对数的底数)的结果实际上应该是 31.0是 31.000000000000004。

然后,Math.ceil(...) 将 31.000000000000004 带到 32,而不是我想要的 31。

有人知道如何解决这个问题吗?

【问题讨论】:

  • 你检查过 Math.round() 方法了吗? 31.505 的预期输出是多少?
  • 我在运行System.out.println(((int) Math.ceil(Math.log((1 << 31) - 2) / Math.log(2))));时看到31,你能提供一个Minimal, Reproducible Example吗?

标签: java logarithm


【解决方案1】:

不是问题。

  1. 问题仅在于当一个数字被除以例如两个不同的整数(int's)时,特别是“数学”和日志方法的结果是“精度”,它期望很可能需要某个自定义级别或默认值原始类型的级别,例如双精度 - 因此小数点后有额外的小数位。

  2. 两点,首先,当一个数字被除以技术上只是一个整数时,例如12 / 3 = 6 与数学和作为一个原始类型 double 它总是有小数点后跟大约六个零左右,最后是一个非 0 的数字。其次,从数学库中可能会看起来更糟,您可以从除法而不是小数位获得对数符号。

最后一点,Math 库不知道答案是什么,直到它这样做,所以使用双精度类型是一种自动转换,无论您如何编写它以确保精度和数据类型的安全。 数据类型的自动交换称为提升(将 int 精度提高到 float)或降级(将精度 double 降低到 float)

并且要将其转换为整数,它将按从该点开始的第一个小数位的规则向上或向下舍入,因此您基本上只需将答案放入“new Double(primativedoubletype)”对象并使用它“intValue”方法。

NB 在它前面放一个 (int) 转换只能确保它在分配(通常从表达式或方法)到一个 int 变量时是一个 int,但它不是提取另一种类型的值的方法一个 int,原始类型必须通过其标准 java 类型类对象及其 primatves 转换器方法进行转换。

int hostBits2 = new Double((double)Math.ceil(Math.log(hosts) / Math.log(2)+1e-10)).intValue();

【讨论】:

    【解决方案2】:

    在舍入时尝试使用 epsilon

    int hostBits2 = (int) Math.ceil(Math.log(hosts) / Math.log(2)+1e-10);
    

    【讨论】:

      猜你喜欢
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多