【问题标题】:Java trunc() method equivalentJava trunc() 方法等效
【发布时间】:2019-10-03 14:00:04
【问题描述】:

java.lang.Math 类有 ceil()、floor()、round() 方法,但没有 trunc() 一个。

同时,我在实践中看到 .intValue() 方法(实际上是 (int) 强制转换)完全符合我对 trunc() 标准含义的期望。

但是我找不到任何具体的文档来确认 intValue() 完全等效于 trunc() 并且从许多角度来看这很奇怪,例如:

  • 描述“以 int 形式返回此 Double 的值(通过 强制转换为 int)" 来自 https://docs.oracle.com/javase/7/docs/api/java/lang/Double.html 确实 不要说它“返回小数的整数部分 号码”之类的。

  • 文章 What is .intValue() in Java? 没有说它的行为类似于 trunc()。

  • 我对“Java trunc 方法”或类似的所有搜索都没有给出 好像我是唯一一个搜索 trunc() 并且好像我 不知道大家都知道的很常见的东西。

我能否以某种方式确认我可以安全地使用 intValue() 来获得用“trunc”模式四舍五入的小数?

【问题讨论】:

  • JLS 中有相当详尽的细节;该描述缺少什么?
  • "完全符合我对 trunc() 标准含义的期望" 也许值得定义您期望 trunc 做的事情。
  • 我认为他指的是精度损失问题,就像浮点数一样。
  • Double.intValue() 的文档的Java 8 version 参考了 Java 语言规范第 5.1.3 节 Narrowing Primitive Conversions;这应该明确地解释“将double 转换为int”是什么意思。
  • 是的!而我读它的方式,“向零舍入” == truncate

标签: java math rounding


【解决方案1】:

你可以使用floorceil来实现trunc

  public static double trunc(double value) { 
      return value<0 ? Math.ceil(value) : Math.floor(value);
  }

使用Google Guava DoubleMath#roundToInt(),您可以将该结果转换为int

  public static int roundToInt(double x, RoundingMode mode) {
    double z = roundIntermediate(x, mode);
    checkInRangeForRoundingInputs(
       z > MIN_INT_AS_DOUBLE - 1.0 & z < MAX_INT_AS_DOUBLE + 1.0, x, mode);
    return (int) z;
  }

  private static final double MIN_INT_AS_DOUBLE = -0x1p31;
  private static final double MAX_INT_AS_DOUBLE = 0x1p31 - 1.0;

【讨论】:

    【解决方案2】:

    所以问题变成了:将 double 转换为 int 是否等于截断

    Java Language Specification 可能有答案。我会引用:

    原始类型的特定转换称为窄化 原始转换:

    [...]

    • 浮点数转字节、short、char、int 或 long
    • double 到 byte、short、char、int、long 或 float

    缩小原语转换可能会丢失有关 数值的整体大小,也可能会丢失精度和 范围。

    [...]

    浮点数到整数类型的窄化转换 T 分两步:

    • 在第一步中,如果 T 是 byte、short、char 或 int,则浮点数将转换为 [...] 一个 int,如下所示:
      • 如果浮点数为 NaN(第 4.2.3 节),则第一步转换的结果为 int 或 long 0。
      • 否则,如果浮点数不是无穷大,则浮点值四舍五入为整数值V,向着四舍五入 使用 IEEE 754 舍入归零模式进行归零(第 4.2.3 节)。然后有 两种情况:
        • 如果T是long,并且这个整数值可以表示为long,那么第一步的结果就是long值V。
        • 否则,如果这个整数值可以表示为int,那么第一步的结果就是int值V。

    IEEE 754-1985 中对此进行了描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-17
      • 2012-01-21
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多