在java中浮动生成意外输出

时间:2013-09-13 19:05:33

标签: java

我正在编写一个带浮动的示例程序,但突然发生了一些奇怪的事情。我真的很感激,如果有人可以解释为什么我会在我的计划中面对这样的行为。

package Programs;

public class FloatTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        float f1 = (float) 3.2;
        float f2 = (float) 6.5;
        if (f1 == 3.2) {
            System.out.println(f1 + " same");
        } else {
            System.out.println(f1 + " different");
        }
        if (f2 == 6.5) {
            System.out.println(f2 + " same");
        } else {
            System.out.println(f2 + " different");
        }
    }
}

输出:

3.2 different
6.5 same

在做了一些改变f2值的测试后,我注意到f2>我得到了意想不到的结果。 3.5为什么?任何意见都非常感谢。

由于

6 个答案:

答案 0 :(得分:5)

我将亲自尝试一下技术解释。由于这些值最终以二进制格式存储,因此在某些条件下精度将会丢失。

6.5不应失去任何精度,因为它可以转换为二进制值110.1

然而,

3.2不能像这样干净地转换,因为.2的二进制表示变得不合理。这将是11.00110011..的内容。这种情况最多只能在转换为另一种方式时四舍五入为3.2

如果有人能够验证我在说什么,那就太棒了 - 这是基于对Java如何处理这个问题的公认有限的知识。

答案 1 :(得分:3)

由于表示浮点变量的方式,并非所有数字都可以精确表示。事实上,很少有人可以。

写作时

float f1 = (float) 3.2;

并将其与3.2进行比较,您将f1(一个float)与3.2进行比较(double3.2作为文字输入是隐含的一个double类型)。在您的语句f1 == 3.2中,f1被隐式转换为double,但到那时,精度已经丢失。这是因为3.2是无法准确表示的数字之一,doublefloat更能做到这一点。

巧合的是,6.5是可以精确表达的数字之一(doublefloat),这是由于Java用来表示浮点的内部方案。这就是为什么,在您的情况下,f2 == 6.5true

答案 2 :(得分:2)

有很多方法可以解决这个问题,

  

出现此问题是因为无法表示小数值   准确地在二进制文件中。

     
      
  1. 具有公差值并检查差异是否小于公差值。
  2.   
  3. 将它乘以10/100 / ...然后比较数字
  4.   
  5. 查看BigDecimal
  6.   

并浏览this for sure.

答案 3 :(得分:2)

:)啊,IEEE754和JVM与浮点数的区别。简而言之,6.5与6.5的浮点值不同。 6.5 == 6.5f会起作用,但你更了解你在做什么!请阅读http://en.wikipedia.org/wiki/IEEE_floating_point,同时注意'strictfp'关键字,以强制跨平台强制IEEE754行为。这里有很多事情需要考虑,舍入行为,预测顺序,JVM差异等。不是整数或长期的东西都是出乎意料的棘手。

您正在操纵数字的二进制表示,该数字具有适用于许多类型的数学计算的精度,其中不需要无限精确的答案。对于许多工程和财务系统,特别是那些涉及乘法或分数的系统,这是不可接受的。您需要重新计算您的会计(使用理解金钱和小数的金融类),(例如以便士计算金钱),而对于工程,您可能需要使用BigDecimal或具有特定舍入行为,percision等的相关类。

再举一个例子,浮点值为1/3 + 1/3 + 1/3,可能也可能不等于1.因为组成数据的数字表示的1和0并不精确为1 / 3。在我的特定平台(JVM 1.6 Windows 64位)上,它是1.0,但它可能不在您的平台上。

答案 4 :(得分:2)

使用演员if (f1 == (float)3.2) {然后它会起作用。

3.2这样的文字是double类型,你正在将float与double进行比较,这会导致这样的事情发生。

  

@JNL指出

     

出现此问题是因为无法在二进制文件中准确表示十进制值。

答案 5 :(得分:1)

虽然看起来似乎不正确,但是当你运行

float f1 = (float) 3.2;

f1并不等于3.2。如上所述,有几种方法可以解决这个问题。