【问题标题】:How to check if a double value has no decimal part [duplicate]如何检查双精度值是否没有小数部分[重复]
【发布时间】:2013-04-12 05:42:51
【问题描述】:

我有一个 double 值,我必须在我的 UI 上显示它。 现在的条件是 double = 0 的十进制值,例如。 - 14.0 在那种情况下,我必须在我的 UI 上只显示 14 个。 此外,这里的字符数上限为 5。

eg.- 12.34 整数值不能大于 2 位,我们的双精度值也是如此。

最好的方法是什么?

【问题讨论】:

    标签: java double


    【解决方案1】:

    你可以这样做

    d % 1 == 0
    

    检查double d是否是一个整体。

    【讨论】:

    • 这个 Double.MIN_VALUE % 1 == 0 给出错误
    • @Evgeniy 毕竟,Double.MIN_VALUE 并不完整。
    • 但是取模只适用于整数,不是吗?
    • 此解决方案不符合 Sonar。最好使用关系运算符,例如小于 ()。例如:d % 1.0 > 0
    【解决方案2】:

    ceil 和 floor 的输出应该相同

    Math.ceil(x.y) == Math.floor(x.y)
    

    或者简单地检查双值是否相等

    x.y == Math.ceil(x.y)
    x.y == Math.floor(x.y)
    

    Math.round(x.y) == x.y
    

    【讨论】:

    • Math.round(x) == x 怎么样,x 是双类型表达式。
    【解决方案3】:

    所有整数都是 1 的模数。所以下面的检查必须给你答案。

    if(d % 1 == 0)
    

    【讨论】:

      【解决方案4】:

      有趣的小问题。这有点棘手,因为实数并不总是代表精确的整数,即使它们是故意的,所以允许公差很重要。

      例如容差可能是 1E-6,在单元测试中,我保持了一个相当粗的容差以得到更短的数字。

      我现在可以阅读的答案都不能以这种方式工作,所以这是我的解决方案:

      public boolean isInteger(double n, double tolerance) {
          double absN = Math.abs(n);
          return Math.abs(absN - Math.round(absN)) <= tolerance;
      }
      

      还有单元测试,以确保它有效:

      @Test
      public void checkIsInteger() {
          final double TOLERANCE = 1E-2;
          assertThat(solver.isInteger(1, TOLERANCE), is(true));
      
          assertThat(solver.isInteger(0.999, TOLERANCE), is(true));
          assertThat(solver.isInteger(0.9, TOLERANCE), is(false));
      
          assertThat(solver.isInteger(1.001, TOLERANCE), is(true));
          assertThat(solver.isInteger(1.1, TOLERANCE), is(false));
      
          assertThat(solver.isInteger(-1, TOLERANCE), is(true));
      
          assertThat(solver.isInteger(-0.999, TOLERANCE), is(true));
          assertThat(solver.isInteger(-0.9, TOLERANCE), is(false));
      
          assertThat(solver.isInteger(-1.001, TOLERANCE), is(true));        
          assertThat(solver.isInteger(-1.1, TOLERANCE), is(false));
      }
      

      【讨论】:

      • double 最多可以精确表示 53 位,因此对于 java 中 int 数据类型的当前定义(严格为 32 位)没有必要容忍。如果原始值从 int 转换为 double,那么它可以精确地转换回来,而不会损失任何精度。请参阅stackoverflow.com/a/43656339/3167374
      【解决方案5】:

      比较两个值:正常的 double 和 flooring 之后的 double。如果它们的值相同,则没有小数部分。

      【讨论】:

        【解决方案6】:

        根据需要使用数字格式化程序来格式化值。请查看this

        【讨论】:

          【解决方案7】:
          double d = 14.4;
          if((d-(int)d)!=0)
              System.out.println("decimal value is there");
          else
              System.out.println("decimal value is not there");
          

          【讨论】:

          • 你应该使用!=而不是&gt;,因为它会在d为负值时返回false。
          • 它不适用于-11111111111111.1;
          • 不适用于Repeating or Endless Decimals,例如Pi or 1/7
          【解决方案8】:

          在比较之前,您可能希望将双精度数舍入到小数点后 5 位左右,因为如果您使用它进行了一些计算,双精度数可能包含非常小的小数部分。

          double d = 10.0;
          d /= 3.0; // d should be something like 3.3333333333333333333333...
          d *= 3.0; // d is probably something like 9.9999999999999999999999...
          
          // d should be 10.0 again but it is not, so you have to use rounding before comparing
          
          d = myRound(d, 5); // d is something like 10.00000
          if (fmod(d, 1.0) == 0)
            // No decimals
          else
            // Decimals
          

          如果您使用的是 C++,我认为没有圆形功能,因此您必须自己实现它,例如:http://www.cplusplus.com/forum/general/4011/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-04-11
            • 1970-01-01
            • 2010-09-20
            • 1970-01-01
            • 2020-05-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多