【问题标题】:Understanding integral division理解积分除法
【发布时间】:2014-10-07 14:39:18
【问题描述】:

我有以下代码:

public static final long KILOMETER_IN_METERS = 1000;

public static int getKilometers(int distanceInMeter) {
    return (int) Math.floor(distanceInMeter / KILOMETER_IN_METERS);
}

对于带有 return 语句的行,Sonar 说:

积分除法结果转换为双精度或浮点数

Here is the full description of this bug.


据我了解,它说存在 int/int 除法,其结果可能是 浮点值,但我可能错了。
我该如何正确处理这种情况?

【问题讨论】:

    标签: java casting integer-division


    【解决方案1】:

    这里不需要使用Math.floorMath.floor 是对double 的一个操作,当你向它提供一个 int 时它什么也不做。

    返回小于或等于参数的最大值(最接近正无穷大)
    double 并且等于一个数学整数。特殊情况:

    • 如果 参数值已经等于一个数学整数,那么 结果与参数相同。
    • 如果参数是 NaN 或无穷大或正零或负零,则 结果与参数相同。

    (Source)

    整数除法已经具有与Math.floor 相同的逻辑行为,即它截断除法运算的其余部分。 int/int 总是返回 int

    例如,100/3 将返回 3340/50 将返回 0

    只需使用此代码:

    public static int getKilometers(int distanceInMeter) {
        return distanceInMeter / KILOMETER_IN_METERS;
    }
    

    【讨论】:

    • 哈,你扩展了你的答案,而我正在扩展你的答案。 :)
    • 谢谢 Eran,但我有 long 类型的常量,在 return distanceInMeter / KILOMETER_IN_METERS; 的结果中我有异常,因为预期为 int,但很早就找到了。
    • @josser 好吧,没有理由让你的常量很长,因为它的值非常小。如果它必须很长,则需要强制转换为 int。
    • 是的,你是对的——只要是一个整数就足够了。至于 Math.floor - 似乎没有必要在这里使用它。谢谢。
    【解决方案2】:

    那是因为Math.floor 将 double 作为参数,而整数除以整数已经是整数。所以所有关于声纳的投射声纳都在那里完成,而不是在你对int的显式投射上。

    这是floor 的文档:http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#floor%28double%29

    【讨论】:

      【解决方案3】:

      为了扩展 Eran 的答案,这就是你正在做的事情:

      distanceInMeter / KILOMETER_IN_METERS 将整数除以整数。在 Java 中,该结果是一个截断的整数。然后你把它放入Math.floor,它需要一个双倍。因此,Java 试图通过将您的 int 变成 double 来帮助您。然后你将Math.floor返回的double转换回int

      如果您一直在关注,您可能已经注意到您已经有了截断的 int。所以你的代码需要很简单:

      public static int getKilometers(int distanceInMeter) {
          return distanceInMeter / KILOMETER_IN_METERS;
      }
      

      【讨论】:

      • 该代码无法编译,KILOMETER_IN_METERS 很长。您需要先将其转换为 int。
      【解决方案4】:

      当你将两个整数相除时,你总是会得到一个整数,向下取整。 如果你划分distanceInMeter / KILOMETER_IN_METERS,然后将其分配给一个双精度,它首先被划分为integer,然后再分配,所以你得到一个向下取整的值,转换为double

      Sonar 不会因为Math.floor 而抱怨 - 它抱怨是因为您将整数除法结果(它本身是向下舍入的integer)转换为double。大多数情况下,这是一个错误(为什么故意自动循环并在之后立即转换为双精度)?

      int distanceInMeter = 505;
      
      double result = distanceInMeter / KILOMETER_IN_METERS;
      System.out.println(result); // 0.0
      
      double result2 = distanceInMeter * 1.0 / KILOMETER_IN_METERS;
      System.out.println(result2); // 0.505
      
      double result3 = ((double) distanceInMeter) / KILOMETER_IN_METERS;
      System.out.println(result3); // 0.505
      
      1.0 * distanceInMeter / KILOMETER_IN_METERS
      ((double)distanceInMeter) / KILOMETER_IN_METERS
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-30
        • 2013-06-04
        • 1970-01-01
        • 2021-02-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 2015-07-10
        相关资源
        最近更新 更多