精华内容
下载资源
问答
  • java double类型运算问题

    千次阅读 2016-04-13 14:12:33
    double i = 0.1; System.out.println(i+i+i); 运行上面的语句,最终的结果是: 很奇怪,并不是想象中的0.3,错误在哪里? 原因:这其实是计算机内部机制导致的问题,具体就是计算机中存储浮点数的机制,导致...

    问题重现:

    double i = 0.1;
    System.out.println(i+i+i);

    运行上面的语句,最终的结果是:


    很奇怪,并不是想象中的0.3,错误在哪里?


    原因:这其实是计算机内部机制导致的问题,具体就是计算机中存储浮点数的机制,导致浮点数如果参与了运算,那么就可能会丧失精度,产生预期之外的结果,当然这里只是可能,有以下运算确实会恰巧复合预期结果。

    那么结论:即尽量不要用double或者float来进行精确运算,会丧失精度。double和float适合科学计算,bigdecimal才适合精确计算。构建bigdecimal用string的参数。所谓的科学计算就是会算出很长的小数,最后按需求取舍就可以了。比如天文学或者化学中的质量测定,都不需要特别精确,取小数点后多少多少位就可以了。但如果是经融或者医疗领域,那就必须精确,不能取舍。


    计算机存储浮点数原理:

    正数存储就是补码(取反加一)。

    浮点数在IEEE中也有详细的表示方式。大致是最高位表示正负,中间的几位表示尾数,最后的几位表示指数。

    具体过程,首先拿到一个十进制的小数,

    1,先将其转换为二进制的小数,整数部分除二取余法,小数部分则是乘二取整法;

    2,移位,使得小数点的左边只有一个1,然后记下移动了多少位,假设是n位,那么指数部分就是n的二进制表示,当然,n可正可负;

    3,根据正负设置符号位

    4,取小数点后面的尾数设置尾数位,因为移位后小数点前面只有一个1,所以这个1不用记录,只要记录小数部分即可;

    5,记录指数部分;

    这就是double或者float在底层的实现。

    从上面的过程可以知道,在将一个十进制的小数的小数部分转换为二进制的小数时,除非最后的一位是5,否则是不可能乘尽的,也就意味着这个十进制的小数是无法用二进制来精确表示的,如果double参与了运算,那么结果肯定有很大的概率不是精确的。这就解释了开始的奇怪结果。要想精确计算最好采用bigdecimal。但是,如果double没有参与运算,直接打印,结果却没有任何问题,这个还没有深究过。



    展开全文
  • Java学习之double类型数据比较

    万次阅读 2017-06-14 09:41:34
    Java学习之double类型数据比较对于两个double类型的数据,是不能直接用==来比较是否相等double a=1.01; double b=1.01; if(b==a){ System.out.println("相等"); }上面的代码是不会在控制台打印信息的double a=1.01;...

    Java学习之double类型数据比较

    对于两个double类型的数据,是不能直接用==来比较是否相等

    double a=1.01;
    double b=1.01;
    if(b==a){
        System.out.println("相等");
    }

    上面的代码是不会在控制台打印信息的

    double a=1.01;
    double b=1.01;
    System.out.println(b==a);

    上面的代码在控制台打印出false

    下面介绍两种比较double数据是否相等的方法。
    1. 转换成字符串之后用equals方法比较
    2. 转换成Long之后用==方法比较

    double a=1.01;
    double b=1.01;
    System.out.println(String.valueof(b)==String.valueof(a));
    System.out.println(Double.doubleToLongBits(a)==Double.doubleToLongBits(b));

    之所以要避免double,float之间的运算原因如下:
    1. float和double是java的基本类型,用于浮点数表示,在java中float占4个字节32位,double占8个字节64位,一般比较适合用于工程测量计算中,其在内存里的存储结构如下:

    float:
    符号位(1 bit)
    指数(8 bit)
    尾数(23 bit)
    double:
    符号位(1 bit)
    指数(11 bit)
    尾数(52 bit)
    注意:从左到右是从低位到高位,而在计算机内部是采用逆序存储的。
    2. System.out.println(2.00-1.10);中的1.10不能被计算机精确存储,以double类型数据1.10举例计算机如何将浮点型数据转换成二进制存储,
    这里重点讲小数部分转换成二进制:
    1.10整数部分就是1,转换成二进制1(这里整数转二进制不再赘述)
    小数部分:0.1
    0.1*2=0.2取整数部分0,基数=0.2
    0.2*2=0.4取整数部分0,基数=0.4
    0.4*2=0.8取整数部分0,基数=0.8
    0.8*2=1.6取整数部分1,基数=1.6-1=0.6
    0.6*2=1.2取整数部分1,基数=1.2-1=0.2
    0.2*2=0.4取整数部分0,基数=0.4
    .
    .
    .
    .
    直至基数为0。1.1用二进制表示为:1.000110…xxxx….(后面表示省略)
    0.1 = 0*2^(-1)+0*2^(-2)+0*2^(-3)+1*2^(-4)+………而double类型表示小数部分只有52位,当向后计算 52位后基数还不为0,那后面的部分只能舍弃,从这里可以看出float、double并不能准确表示每一位小数,对于有的小数只能无限趋向它。在计算机 中加减成除运算实际上最后都要在计算机中转换成二进制的加运算,由此,当计算机运行System.out.println(2.00-1.10);
    时会拿他们在计算机内存中的二进制表示计算,而1.10的二进制表示本身就不准确,所以会出现0.8999999999999999的结果。

    但为什么System.out.println(2.00f-1.10f);得出的结果是0.9呢。因为float精度没有double精度那么大,小数部分0.1二进制表示被舍去的比较多。

    注意:

    程序中应尽量避免浮点数的比较
    float、double类型的运算往往都不准确
    解决方法:

    使用BigDecimal提供的方法进行比较或运算,但要注意在构造BigDecimal的时候使用float、double的字符串形式构建,BigDecimal(String val);为什么不用BigDecimal(double val)API里写的比较清楚。

    运算以减法为例:

    BigDecimal b1 = new BigDecimal(Double.toString(2.00));

    BigDecimal b2 = new BigDecimal(Double.toString(1.10));

    double result = b1.subtract(b2).doubleValue();

    展开全文
  • 目录 ...double类型之间的运算不能直接使用Double来直接进行运算:因为计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法...

    目录

     

    问题:

    原因:

    处理方法:

    处理代码:


    问题:

    刚开始时候,是直接用double去进行加减。但是后来发现,原本3570竟然显示成:3569.9999999999995

     

    原因:

    double类型之间的运算不能直接使用Double来直接进行运算:因为计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。

        在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

     

    处理方法:

      在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

         1、用float或者double变量构建BigDecimal对象。例如:

         BigDecimal bd1 = new BigDecimal(Double.toString(d1)); 
            BigDecimal bd2 = new BigDecimal(Double.toString(d2));

     
         2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。
         3、把BigDecimal对象转换成float,double,int等类型。
        进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。例如:

    d1.add(bd2).doubleValue()

    处理代码:

    DoubleUtils
    import java.math.BigDecimal;
    
    public class DoubleUtil {
         /** 
         * double 相加 
         * @param d1 
         * @param d2 
         * @return 
         */ 
        public static double sum(double d1,double d2){ 
            BigDecimal bd1 = new BigDecimal(Double.toString(d1)); 
            BigDecimal bd2 = new BigDecimal(Double.toString(d2)); 
            return bd1.add(bd2).doubleValue(); 
        } 
    
    
        /** 
         * double 相减 
         * @param d1 
         * @param d2 
         * @return 
         */ 
        public static double sub(double d1,double d2){ 
            BigDecimal bd1 = new BigDecimal(Double.toString(d1)); 
            BigDecimal bd2 = new BigDecimal(Double.toString(d2)); 
            return bd1.subtract(bd2).doubleValue(); 
        } 
    
        /** 
         * double 乘法 
         * @param d1 
         * @param d2 
         * @return 
         */ 
        public static double mul(double d1,double d2){ 
            BigDecimal bd1 = new BigDecimal(Double.toString(d1)); 
            BigDecimal bd2 = new BigDecimal(Double.toString(d2)); 
            return bd1.multiply(bd2).doubleValue(); 
        } 
    
    
        /** 
         * double 除法 
         * @param d1 
         * @param d2 
         * @param scale 四舍五入 小数点位数 
         * @return 
         */ 
        public static double div(double d1,double d2,int scale){ 
            //  当然在此之前,你要判断分母是否为0,    
            //  为0你可以根据实际需求做相应的处理 
            BigDecimal bd1 = new BigDecimal(Double.toString(d1)); 
            BigDecimal bd2 = new BigDecimal(Double.toString(d2)); 
            return bd1.divide(bd2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); 
        } 
    
        /**
         * double 转 string 去掉后面锝0
         * @param i
         * @return
         */
        public static String getString(double i){
            String s = String.valueOf(i);
            if(s.indexOf(".") > 0){
             //正则表达
                   s = s.replaceAll("0+?$", "");//去掉后面无用的零
                   s = s.replaceAll("[.]$", "");//如小数点后面全是零则去掉小数点
             }
            return s;
        }
    
        public static void main(String[] args) {
            String i=numberToBits("10000000.01");
            System.out.println(i);
        }
        /**
         * 数字转换为千位符
         * @param number
         * @return
         */
        public static String numberToBits(String number){
            String begin="";
            String end="";
            String[] num=number.split("\\.");
            if(num.length>1){
                begin=num[0];
                end=num[1];
            }else{
                begin=number;
            }
            return begin.replaceAll("(?<=\\d)(?=(?:\\d{3})+$)", ",")+"."+end;
        }
    
    
    }

     

    参考链接:

    https://blog.csdn.net/qq_28009065/article/details/78047827

    https://blog.csdn.net/iilegend/article/details/80362272

    展开全文
  • double是基本数据类型Double是原始数据类型 double没有方法,Double有自己的属性和方法 double只创建引用,Double创建对象 集合类不能存放double,只能存放Double double存放在栈中,Double存放在堆中 栈的...

    double是基本数据类型,Double是原始数据类型
    double没有方法,Double有自己的属性和方法
    double只创建引用,Double创建对象
    集合类不能存放double,只能存放Double
    double存放在栈中,Double存放在堆中
    栈的存取速度要高于堆,另外栈中的数据可以共享
    如:
    double a = 0;
    double b = 0;
    不会创建对象,只会建立两个引用,同时指向变量“0”(栈数据共享)

    Double a = new Double(0);
    Double b = new Double(0);
    会创建两个对象,即使对象所代表的值一样(堆数据不共享)
    所以从效率来讲用double合适,而Double提供的属性和方法会使操作各种操作更加方便和灵活
    例如:

    package inheritance;
    import java.time.*;
    /**
     *
     * @author cmx
     */
    public class hashCode {
        public static void main(String[] args)
        {
            /**
             * hashCode对象的test
             */
            String n="hello";
            double salary=12.0;
            Double salary1=new Double(salary);  //有这个就可以运行
            LocalDate hireDay= LocalDate.now();  //而不是 LocalDate hireDay=new LocalDate();
            System.out.println(n.hashCode());
            System.out.println(salary1.hashCode());
            System.out.println(hireDay.hashCode());
        }
    
    }
    

    对比与以下就不可以运行

    package inheritance;
    import java.time.*;
    /**
     *
     * @author cmx
     */
    public class hashCode {
        public static void main(String[] args)
        {
            /**
             * hashCode对象的test
             */
            String n="hello";
            double salary=12.0;
         //   Double salary1=new Double(salary);  注意
            LocalDate hireDay= LocalDate.now();  //而不是 LocalDate hireDay=new LocalDate();
            System.out.println(n.hashCode());
            System.out.println(salary.hashCode());  //注意salary而不是salary1
            System.out.println(hireDay.hashCode());
        }
    
    }
    

    区别在于:double salary; 中salary不是对象
    而Double salary1=new Double(salary);构造了一个对象
    hashCode只能做用于对象
    将double类型的数值的hashCode方法,除了将double转为Double,还可以采用以下方法:
    Double.hashCode(double value)
    例如:

    package inheritance;
    import java.time.*;
    /**
     *
     * @author cmx
     */
    public class hashCode {
        public static void main(String[] args)
        {
           /**
            * Double.hashCode
            */
            double salary=12.0;
            System.out.println(Double.hashCode(salary));
            /**
             * run:
    1076363264
    成功构建 (总时间: 0 秒)
    
             */
        }
    
    }
    展开全文
  • 深入理解Java注解类型(@Annotation)

    万次阅读 多人点赞 2017-05-21 10:51:43
    【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) ...深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解
  • java算法:构建

    2012-10-26 12:39:57
    java算法:构建块   在java中用来存储和处理信息的主要的低级构造。使用java的类来描述要处理的信息,定义要处理它们的方法,并构建能实际存储这些数据的...在java中,基本的数据类型构建起来有:boolean,char,
  • 1.01-1=0.010000000000000009? 我们先来看一段代码public class Test_1 { public static void main(String[] args) { String e = "1.01";//这里顺便写下把一个小数分为整数和... double s = Double.valueOf(e);//1.01
  • java HttpServer构建http服务器

    万次阅读 多人点赞 2014-11-12 16:00:34
    package com.tdt.server.httpserver; import java.io.IOException; import java.net.InetSocketAddress; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.spi.HttpServerProvider; /**
  • java.lang.Double常用方法

    千次阅读 2019-01-31 11:07:28
    通过指定的double构建一个Double对象。 Double(String s) 通过指定的String值构建一个Double对象。 +方法 byte byteValue() 将此对象转化为byte。 double doubleValue() 将此对象转化为double。 long long...
  • Javadouble和float的比较及使用

    千次阅读 2019-11-21 19:24:24
    java中运行一下代码 System.out.println(2.00-1.10); 输出的结果是:0.8999999999999999 很奇怪,并不是我们想要的值0.9 再运行如下代码: System.out.println(2.00f-...在java中浮点型默认是double的,及2.00和1....
  • 测试Double的parseDouble方法,即,首先将字符串"12345.00"转换为double类型并输出结果,然后,将字符串"¥12345.00"转换为double类型,并查看运行效果。 方案 首先,使用Double的parseDouble方法,将字符串"12345...
  • 前面的文章有介绍:为了解决装箱带来的效率问题,java8针对原始类型提供了一些特化的函数式接口,如:IntPredicate。流也不例外,它提供了3个的原始类型数值流: IntStream LongStream DoubleStream 分别将流中的...
  • 使用Java构建json

    千次阅读 2018-08-30 15:19:21
    注:这里要使用到json.jar包 ...import java.util.HashMap; import java.util.Map; import org.json.JSONObject; import bean.DiaoSi; public class CreateJson { public static void main(...
  • 关于java中的double check lock

    千次阅读 2017-09-07 21:55:17
    ##实现一个正确的单例模式 在熟悉的单例模式中你或许会遇到...https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html 2. https://www.ibm.com/developerworks/java/library/j-dcl/index.html
  • 1、用float或者double变量构建BigDecimal对象。 2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。 3、把BigDecimal对象转换成float,double,int等类型。 一般来说,可以使用BigDecimal的...
  • 深入理解(1)Java注解类型(@Annotation)

    万次阅读 2019-05-01 10:28:09
    理解Java注解 实际上Java注解与普通修饰符(public、static、void等)的使用方式并没有多大区别,下面的例子是常见的注解: public class AnnotationDemo { //@Test注解修饰方法A @Test pub...
  • Java构建汽车无人驾驶:汽车目标检测 Java Autonomous Driving: Car Detection 原文地址: https://dzone.com/articles/java-autonomous-driving-car-detection-1 在这篇文章中,我们将用Java构建一个实时视频...
  • 虽然Java是面向对象的语言,但是没有基础类型也就没有复杂类型(出了基础类型外的其它类型),复杂类型是基础类型的基础上构建而来。 8大基础类型分别是boolean、byte、short、int、long、float、double、char。 可以...
  • 深入理解Java注解类型(@Annotation)

    万次阅读 多人点赞 2018-08-05 21:33:39
    java注解是在JDK5时引入的新特性,鉴于目前大部分框架(如Spring)都使用了注解简化代码并提高编码的效率,因此掌握并深入理解注解对于一个Java工程师是来说是很有必要的事。本篇我们将通过以下几个角度来分析注解的...
  • Java基本类型和数据结构

    千次阅读 2018-07-20 13:52:09
    基本类型 精度丢失和溢出: 精度丢失一般发生在浮点型存储数值或类型强制转换的时候。我们知道计算机存储数值实际存储的是二进制,举个粟子 double r1 = 1 - 0.99; double r2 = 2 - 0.99 result的值是0....
  • Java常用引用类型

    2016-11-27 22:27:40
    Java常用引用类型,包括数组、Arrays、String、Calendar类
  • Java八大基本数据类型

    万次阅读 多人点赞 2020-12-17 09:58:05
    Java基本数据类型图: 整数类型:byte 1字节,8位,最大存储数据量是255,存放的数据范围是-128~127之间。 构造方法: public Byte(byte value) 构建了一个新分配的Byte表示指定的byte价值。 参数 value -被 ...
  • 一、引言 什么是RTTI RTTI(Run-Time Type ...Java中的RRTI则是源于《Thinking in Java》一书,可以在程序运行时发现和使用类型信息。这使得我们从只能在编译期执行面向类型的操作中解脱出来。主要有两种方...
  • Java中 float、double使用注意问题

    千次阅读 2014-02-11 15:56:14
    java中运行一下代码 System.out.println(2.00-1.10); 输出的结果是:0.8999999999999999 很奇怪,并不是我们想要的值0.9 再运行如下代码: System.out.println(2.00f-1.10f); 输出结果:0.9 又正确了,为什么会...
  • Java中,抽象类Number是BigDecimal、BigInteger、Byte、Double、Float、Integer、Long和Short类的超类。该类提供了六个方法,如图-1所示。 byte byteValue() 以byte形式返回指定的数值。 ...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    文章目录Java概述何为编程什么是Javajdk1.5之后的三大版本JVM、JRE和JDK的关系什么是跨平台性?原理是什么Java语言有哪些...Java和C++的区别Oracle JDK 和 OpenJDK 的对比基础语法数据类型Java有哪些数据类型switc...
  • Java 处理货币类型

    千次阅读 2018-12-27 15:19:59
    今天get到了一个炒鸡好用的处理货币的类型!BigDecimal 还有相关格式---&gt; NumberFormat public static void main(String[] args){ double a = 0.03; double b = 0.02; double c= a-b; } 把c打印...
  • 最近在读Hadoop#Yarn部分的源码,读到状态机那一部分的时候,感到enmu的用法实在是太灵活了,在给...原文链接:http://www.javacodegeeks.com/2011/07/java-secret-using-enum-to-build-state.html 作者:Peter Lawrey
  • 如何使用Java构建一个动态数组类

    千次阅读 2019-09-04 22:37:08
    数组基础 数组作为数据结构最大的优点在于可以快速查询,arr[2]。但由于数组的大小在开始...这里我们假设要创建一个int类型的数组类。在开头先定义好我们这个类中有一个数组data[],以及数组中实际存放的元素数量...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 57,118
精华内容 22,847
关键字:

java的double类型的构建

java 订阅