java bigDecimal and double

Java BigDecimal和double

BigDecimal是Java中用来表示任意精确浮点数运算的类,在BigDecimal中,使用unscaledValue × 10-scale来表示一个浮点数。其中,unscaledValue是一个BigInteger,scale是一个int。从这个表示方法来看,BigDecimal只能标识有限小数,不过可以表示的数据范围远远大于double,在实际应用中基本足够了。

下面提一下两个精度问题:
问题一:BigDecimal的精度问题(StackOverflow上有个家伙问了相关的问题)
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,否则会抛出异常。
问题二:把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)。

转载于:https://www.cnblogs.com/yelongsan/p/4120913.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/406747.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++字节对齐问题

From: http://blog.csdn.net/alex_bn/article/details/6770788 首先来看下在C/C中定义如下的结构体,然后对他们分别进行sizeof()运算,看看结果会如何 struct A { int a; char b; short c; }; struct B { char b; int a; …

一起来看流星雨剧情简介/剧情介绍/剧情分集介绍第六集

云海为了应战雨荨的挑战,去学院雕像拜传说中的考神,祈祷自己能通过考试。上官、叶烁为了帮助云海通过考试,特意买来了高级的作弊系统。考场上,云海突然傲气发作,一把扔掉了作弊的笔,不巧正好落在雨荨的座位…

Sublime Text添加插入带当前时间说明

作者:木尘 日期:2014-11-25 插件实现插入带时间功能的说明: 1. 创建插件: Tools → New Plugin: import datetime import sublime_plugin class AddInfoCommand(sublime_plugin.TextCommand):def run(self, edit):self.view.run_c…

VC调用C#写的DLL

From: http://hi.baidu.com/ocnc/blog/item/2c7fc45c1d1f1051fbf2c0ea.html VC中调用C#写的DLL时,对C#这边的DLL有要求,即要在.NET这边以COM方式生成DLL; 步骤: 1.创建类库;类库的创建必须分为接口和实现类&#xff…

React开发(144):Git Commit 规范

#### feature: 开发新的功能 fix: 修复bug refactor: 代码重构 docs: 文档修改 style: 代码格式修改, 注意不是 css 修改 perf: 改善性能 build: 变更项目构建或外部依赖(例如scopes: webpack、gulp、npm等) revert: 代码回退 比如&#…

[转]程序实现调用迅雷(以C#为例)

1.首先导入DLL 添加引用 -> COM -> ThunderAgent 1.0 Type Library(前提是已安装迅雷) 或者C:\Program Files\Thunder Network\Thunder\ComDlls\ThunderAgent_Now.dll(路径可能有所不同) 2.代码: THUNDERAGENTLi…

PHP Yii框架中使用smarty模板

第一种方法 按照YII系统的办法生成视图觉得有点麻烦,觉得用smarty更省事。尝试着把smarty模板加进来了。 date_default_timezone_set("PRC"); class PlaceController extends CController { protected $_smarty; function __construct(){ parent::__const…

COM应用实例--获取桌面墙纸路径

COM应用实例--获取桌面墙纸路径&#xff1a;Win32控制台程序(C) /*功能&#xff1a; 获取桌面墙纸的路径&#xff0c;并建立一个该墙纸的快捷方式保存在指定路径说明&#xff1a; COM应用实例, Win32控制台程序 */ #include <iostream> #include <afx.h> #include …

React开发(145):目录规范:

config ├── config.js umi 配置目录 ├── plugin.config.js webpack插件配置目录 └── router.config.js 路由配置目录 src: 静态资源目录: assets 公共组件目录&#xff1a;common 业务组件目录: components 主框架目录&#xff1a;layouts 国际化目录&…

献给网页开发者的20款Firefox插件

毫无疑问&#xff0c;比起其他浏览器&#xff0c;Chrome虽有着明显的优势&#xff0c;但是它的劲敌Firefox却是很多前端攻城师和研发人员的挚爱&#xff0c;为了尽可能地提高用户体验&#xff0c;Firefox的社区在插件开发和运用上有着丰富的经验&#xff0c;说它是网站开发者的…

VC6重载字体对话框,去除颜色下拉框

为了去除字体对话框中的颜色下拉框&#xff0c;我们需要重载字体对话框类&#xff1a;CFontDialog 1. 创建一个MFC Class&#xff0c;继承自CFontDialog: // MyFontDialong.h : header file //// CMyFontDialong dialogclass CMyFontDialong : public CFontDialog {DECLARE_DY…

Mac系统下如何使用命令行方式启动MySQL

首先&#xff0c;先去官网下载MySQL&#xff0c;选择Mac版本的DMG格式的文件。 官网地址为&#xff1a;dev.mysql.com/downloads/mysql/5.7.html 然后下载后&#xff0c;直接双击对应的dmg格式的文件进行安装即可。接下来&#xff0c;我们可以先看下如何在系统偏好设置中启动M…

React开发(146):开发规范

1&#xff0c;编辑器尽量用 VSCode&#xff0c;然后装 Prettier 插件 简单的代码规范 2&#xff0c;缩进2个空格&#xff0c;如果是tab 也设置成2个空格 3&#xff0c;命名时尽量用英文&#xff0c;文件名&#xff0c;组件名等&#xff0c;单词多的可以大写简写。 4&#xff0…

禁止微信公众号页面上下滑动

data(){return {handler: function(e) {e.preventDefault();}, //阻止body滑动} }, methods: {closeTouch: function() {document.getElementsByTagName("body")[0].addEventListener("touchmove", this.handler, { passive: false }); //阻止默认事件}, o…

权限管理系统系列之序言

权限管理系统我相信每个系统都会需要&#xff0c;所以设计一个好的权限管理系统会在系统开发中起到至关重要的作用&#xff0c;节省人力成本和资源&#xff0c;可以不用每次都为权限设计煞费心机。可能每个公司对权限的设计大体相同&#xff0c;略有不同&#xff0c;但是都会不…

linux借助expect完成自动登录

From: http://www.cnblogs.com/sunss/archive/2010/12/23/1914763.html 在工作中&#xff0c;我需要把远程服务器上的文件&#xff0c;拷贝到本地&#xff0c;可是scp的时候必须输入密码&#xff0c;用here文档又不能实现&#xff0c;终于找到一个好东东&#xff0c;expect ,可…

android之隐示意图跳转启动另一个activity

主面板布局&#xff1a;layout/activity_main.xml <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android" android:layout_width"match_parent" android:layout_height"match_parent" android:orientation"…

linux培训课程第六天:ppt以及笔记

第六天授课大纲介绍&#xff1a;第十讲&#xff1a;引导服务器dhcp和NIS这里dhcp服务比较简单,说明一下&#xff0c;首先将dhcp做成功,然后有个dhcp中继,做起来很简单,最主要大家要理解&#xff0c;中继是处在怎样的环境中&#xff0c;你怎样去搭配,这个明白了&#xff0c;下面…

微信公众号 H5 页面中点击一个按钮调起手机的电话拨打功能

1、在H5页面中调起手机的电话拨打功能其实很简单就能实现&#xff1a; <a href"tel:13556891235">点击给我打电话</a>2、在H5页面中调起手机发送短信&#xff1a; <a href"sms:18688888888">发短信</a>3、要想实现点击一个按钮我…

React开发(147):开发注意

## 列表查询做法&#xff1a; 以下查询条件值包括&#xff1a;普通查询和高级查询 1. 首先普通查询和高级查询的值是不相互关联的。 2. 点击查询按钮时会重置 pageIndex 为1&#xff0c;否则查询结果有误差 2. 重置不会重置列表 title 的 sort 和 filter&#xff0c;也不会重置…