一、简介

1、对于不需要任何准确计算精度的数字可以直接使用浮点型,但是如果需要精确计算的结果,则必须使用定点型(BigDecimal类)

浮点型:float,double

定点型:BigDecimal

2、BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。

二、常见问题

1、BigDecimal的精度问题

System.out.println(new BigDecimal(0.1).toString()); // 0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal("0.1").toString()); // 0.1
System.out.println(new BigDecimal(
Double.toString(0.1000000000000000055511151231257827021181583404541015625)).toString());// 0.1
System.out.println(new BigDecimal(Double.toString(0.1)).toString()); // 0.1

分析一下上面代码的问题(注释的内容表示此语句的输出)

第一行:事实上,由于二进制无法精确地表示十进制小数0.1,但是编译器读到字符串"0.1"之后,必须把它转成8个字节的double值,因此,编译器只能用一个最接近的值来代替0.1了,即0.1000000000000000055511151231257827021181583404541015625。因此,在运行时,传给BigDecimal构造函数的真正的数值是0.1000000000000000055511151231257827021181583404541015625。
第二行:BigDecimal能够正确地把字符串转化成真正精确的浮点数。
第三行:问题在于Double.toString会使用一定的精度来四舍五入double,然后再输出。会。Double.toString(0.1000000000000000055511151231257827021181583404541015625)输出的事实上是"0.1",因此生成的BigDecimal表示的数也是0.1。
第四行:基于前面的分析,事实上这一行代码等价于第三行
 
结论:
1.如果你希望BigDecimal能够精确地表示你希望的数值,那么一定要使用字符串来表示小数,并传递给BigDecimal的构造函数。
2.如果你使用Double.toString来把double转化字符串,然后调用BigDecimal(String),这个也是不靠谱的,它不一定按你的想法工作。
3.如果你不是很在乎是否完全精确地表示,并且使用了BigDecimal(double),那么要注意double本身的特例,double的规范本身定义了几个特殊的double值(Infinite,-Infinite,NaN),不要把这些值传给BigDecimal,否则会抛出异常。
 

2、把double强制转化成int,难道不是扔掉小数部分吗?

int x=(int)1023.99999999999999; // x=1024为什么?

原因还是在于二进制无法精确地表示某些十进制小数,因此1023.99999999999999在编译之后的double值变成了1024。

所以,把double强制转化成int确实是扔掉小数部分,但是你写在代码中的值,并不一定是编译器生成的真正的double值。
验证代码:
double d = 1023.99999999999999;
int x = (int) d;
System.out.println(new BigDecimal(d).toString()); // 1024
System.out.println(Long.toHexString(Double.doubleToRawLongBits(d))); // 4090000000000000
System.out.println(x); // 1024

前面提过BigDecimal可以精确地把double表示出来还记得吧。

我们也可以直接打印出d的二进制形式,根据IEEE 754的规定,我们可以算出0x4090000000000000=(1024)。

【Java基础】16、小数的浮点型和定点型的更多相关文章

  1. python小白入门基础(四:浮点型和布尔型)

    # Number (int float bool complex)# (1) float 浮点型 也就是小数# 表达方式一floatvar = 0.98print(floatvar)print(typ ...

  2. Java基础16:Java多线程基础最全总结

    Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...

  3. 【java基础 16】抽象类和接口的区别

    导读:前两天闲着没事儿,看了本书,然后写了点代码,在接口里面写了默认方法实现,因为书上说这个特性是从java8开始的,我还特地给测了一下java7. 没过几天,就有一个技术分享会,刚好也是讲java8 ...

  4. java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)

    1.异常的体系 /* ------|Throwable:所有异常和错误的超类 ----------|Error(错误):错误一般用于jvm或者硬件引发的问题,所以我们一般不会通过代码去处理错误的 -- ...

  5. Java 基础------16进制转2进制

    我们知道,数字8用二进制表示为:1000 用16进制表示为:8 那么我给你一个16进制的数字,0x7f,他的二进制是什么呢? 一个16进制的位数,用4位表示.比如,0x 7 f 其中: 7用4位二进制 ...

  6. Java 基础,小数百分比两种方法

    public static void main(String[] args) { System.out.println(getPercent(1, 2)); } public static Strin ...

  7. java基础(16):正则表达式、Date、DateFormat、Calendar

    1. 正则表达式 1.1 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配 ...

  8. mysql数据类型——浮点和定点型

    mysql数据类型 字节 含义 float(m,d)           4字节  单精度浮点型,8位精度,m是十进制数字的总个数,d是小数点后面的数字个数 double(m,d)        8字 ...

  9. java 基础--8 种基本数据类型:整型、浮点型、布尔型、字符型 整型中 byte、short、int、long 的取值范围 什么是浮点型?什么是单精度和双精度?为什么不能用浮点型表示金额?

     一.8种基本数据类型(4整,2浮,1符,1布): 整型:byte(最小的数据类型).short(短整型).int(整型).long(长整型): 浮点型:float(浮点型).double(双精度浮点 ...

随机推荐

  1. CSRF 攻击(跨域攻击)

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  2. h5面试题

    一.匿名函数实现阶乘第一种写法: 43 > F = fun(Func, 1) -> 1;43 > (Func, N) -> N * Func(Func, N - 1) end. ...

  3. Eclipse 中 Spring 项目的 XML 配置文件报错 Referenced file contains errors

    原来运行正常的项目,突然在applicationContext.xml 文件头报错 总结一下网上的解决方案: 1.有可能网络状况不好导致 如果使用Maven构建项目,spring在加载xsd文件时总是 ...

  4. C 单向链表的创建、插入及删除

    链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用.链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节 ...

  5. Python - GUI(Graphical User Interface,图形用户界面)

    Tkinter https://docs.python.org/3/library/tkinter.html Python自带的标准GUI库,可用于快速创建GUI应用程序,能够满足基本的GUI程序要求 ...

  6. Kubernetes 笔记 01 初识 Kubernetes 新时代的领航者

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 大明王朝时期, ...

  7. 西安活动 | 9月15号 "拥抱开源, 又见.NET" 线下交流活动

    随着.NET Core的发布和开源,.NET又重新回到了人们的视野.除了开源.跨平台.高性能以及优秀的语言特性,越来越多的第三方开源库也出现在了github上——包括ML.NET机器学习.Xamari ...

  8. leetcode — plus-one

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...

  9. leetcode — rotate-image

    import java.util.Arrays; /** * Source : https://oj.leetcode.com/problems/rotate-image/ * * Created b ...

  10. MFC控件编程之复选框单选框分组框

    MFC控件编程之复选框单选框分组框 一丶分组框 分组框 英文叫做 GroubBox 添加了分组框主要就是分组.好看.不重点介绍 二丶单选框 英文: Raido Button 单选框需要注意的事项 1. ...