zoukankan      html  css  js  c++  java
  • 判断浮点数是否相等

    1. 浮点数 == 什么时候出现问题

    1.1 都为小数或整数,不参与运算

    /**
    *无论 a = 0.1 or 1.0 or 1.1   结果都为true
    */
    public static void main(String[] args){
    	double a = 0.1;
    	double b = 0.1;
    	float c = 0.1f;
    	float d = 0.1f;
    
        System.out.println("a==b : "+ (a == b));
    
    	System.out.println("c==d : "+ (c == d));
    }
    

    1.2 参与加减法

    1.2.1 纯小数 + 纯小数 or 纯整数

    public static void main(String[] args){
    	double a = 0.1;
    	double b = 0.1;
    	float c = 0.1f;
    	float d = 0.1f;
        
    	a  = a + 1 - 1; //不论是 1 or 1.0 or 1.1,只要大于0.101 均输出 false
       	//b = b + 1 - 1; 若执行此行,则输出 true
    	System.out.println("a==b : "+ (a == b)); //输出 false
        
    	c = c + 0.1f - 0.1f;
        
    	System.out.println("c==d : "+ (c == d)); //输出 true
    }
    

    1.2.2 纯整数 + 纯小数 or 纯整数

    public static void main(String[] args){
        double a = 1;
        double b = 1;
        float c = 1f;
        float d = 1f;
    
        a  = a + 0.1 - 0.1;
    
        c = c + 1f - 1f;
    
        System.out.println("a==b : "+ (a == b)); // true
    
        System.out.println("c==d : "+ (c == d)); // true
    }
    

    1.2.3 非纯整数 + 纯小数 or 纯整数

    public static void main(String[] args){
        double a = 1.1;
        double b = 1.1;
        float c = 1.1f;
        float d = 1.1f;
    
        a = a + 1 - 1;
    
        c = c + 0.1f - 0.1f;
    
        System.out.println("a==b : "+ (a == b));// true
    
        System.out.println("c==d : "+ (c == d));// true
    }
    

    1.3 个人总结

    以上测试都是放屁,换个数值又会出问题,规律我是不会去找了,还是用别的方法吧

    2. == 和 equals 的区别

    == equals
    基础数据类型:比较他们的值是否相等
    引用数据类型:比较的是引用的地址是否相同 所指向对象的内容是否相等

    String 类的 equals()方法源码

    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
    

    简单说,判断规则

    1. 引用不同,不相等
    2. 类型不同,不相等
    3. 长度不同,不相等
    4. 字符不同,不相等

    当且仅当参数不是null且是String对象表示与此对象相同的字符序列时,结果为true

    3.浮点数相等的判断方法

    3.1 绝对值比较,看精度要求情况

    private static void doubleCompare(double dby,double dbx){
        final double epsilon = 0.0000001;
        if(Math.abs(dby - dbx) < epsilon){
            System.out.println("绝对值比较结果: true");
        }else{
            System.out.println("绝对值比较结果: false");
        }
    }
    

    3.2 转换成字符串后使用 equals 方法比较

    private static void doubleCompare(double dby,double dbx){
    	System.out.println("字符串 equals方法比较结果 : "+ Double.toString(dby).equals(Double.toString(dbx)));
    }
    

    3.3 Double.doubleToLongBits()方法比较

    public static long doubleToLongBits(double value)

    根据IEEE 754浮点“双格式”位布局返回指定浮点值的表示形式。

    位63(由掩码0x8000000000000000L选择的位)表示浮点数的符号。 比特62-52(由掩码0x7ff0000000000000L选择的比特)表示指数。 比特51-0(由掩码0x000fffffffffffffL选择的比特)表示0x000fffffffffffffL的有效数(有时称为尾数)。

    如果参数为正无穷大,则结果为0x7ff0000000000000L

    如果参数为负无穷大,则结果为0xfff0000000000000L

    如果参数为NaN,则结果为0x7ff8000000000000L

    在所有情况下,结果都是一个long整数,当给定longBitsToDouble(long)方法时,将生成与doubleToLongBits的参数相同的浮点值(除了所有NaN值都折叠为单个“规范”NaN值)。

    • 参数

    value - 精度为 double浮点数。

    • 结果

    表示浮点数的位。

    private static void doubleCompare(double dby,double dbx){
    	System.out.println("Long 的 == 方法比较结果 : "+ (Double.doubleToLongBits(dby) == Double.doubleToLongBits(dbx)));
    }
    

    3.4 使用BigDecimal类型的equals方法或compareTo方法

    /**
    * 两种方法均先判断构造方法参数是否相同,不同均返回 false
    * compareTo 只比较数值大小,不比较比例
    * equals 需要比较数值和比例大小,都相等,才返回 true,以下测试结果和预期不同,原因未知
    */
    private static void doubleCompare(){
    	System.out.println(new BigDecimal("0.1").equals(new BigDecimal("0.10")));  //输出false  
    	System.out.println(new BigDecimal("0.1").compareTo(new BigDecimal("0.10")) == 0); //输出true  
        		          
    	System.out.println(new BigDecimal(0.1).equals(new BigDecimal("0.10"))); //输出false
    	System.out.println(new BigDecimal(0.1).compareTo(new BigDecimal("0.10")) == 0); //输出false  
        		     
    	System.out.println(new BigDecimal(0.1).equals(new BigDecimal(0.10))); //输出true  
    	System.out.println(new BigDecimal(0.1).compareTo(new BigDecimal(0.10)) == 0);//输出true 
    }
    

        • public int compareTo(BigDecimal val)
          

          将此BigDecimal与指定的BigDecimal 。 通过此方法,两个值相等但具有不同比例(如2.0和2.00)的BigDecimal对象被视为相等。 对于六个布尔比较运算符(<,==,>,> =,!=,<=)中的每一个,优先考虑该方法。 建议执行这些比较的习惯用法是: (x.compareTo(y) < op > 0) ,其中< op >是六个比较运算符之一。

          • Specified by:

            compareTo ,界面 Comparable

          • 参数

            val - BigDecimal这个 BigDecimal要比较。

          • 结果

            -1,0或1,因为该 BigDecimal在数值上小于,等于或大于 val


        • public boolean equals(Object x)
          

          将此BigDecimal与指定的Object进行相等性比较。 与compareTo不同,此方法仅考虑两个BigDecimal对象的值和比例相等(因此通过此方法比较时2.0不等于2.00)。

          • 重写:

            equals ,类 Object

          • 参数

            x - ObjectBigDecimal比较。

          • 结果

            true当且仅当指定的 ObjectBigDecimal其值和比例等于此 BigDecimal

          • 另请参见:

            compareTo(java.math.BigDecimal)hashCode()

  • 相关阅读:
    面试话痨(四)常量在哪里呀,常量在哪里
    面试话痨(三)我会锁的四种配法,您配吗?
    面试话痨(二)C:JAVA String,别以为你穿个马甲我就不认识你了
    面试话痨(一)让我们来热切的讨论这个养猪场吧
    (JAVA)String类型的逻辑语句编译
    小白的REDIS学习(二)-链表
    小白的Redis学习(一)-SDS简单动态字符串
    mongo中的游标与数据一致性的取舍
    spring-data-mongodb与mongo shell的对应关系
    spring-data-mongodb 使用原生aggregate语句
  • 原文地址:https://www.cnblogs.com/huaranmeng/p/12668903.html
Copyright © 2011-2022 走看看