网站首页  |   业界社区  |  电信社区  |  技术社区   |  极客社区  |  游戏社区  |  生活社区   |   科技博客  |   同事录
TechWeb-技术社区


标题: [java] 为什么1.9+0.3不等于2.2???
生活周刊
TW金牌会员
Rank: 6Rank: 6



UID 117203
精华 16
积分 1388
帖子 747
阅读权限 70
注册 2007-3-12
状态 离线
发表于 2008-8-28 14:15 资料 短消息 加为好友
为什么1.9+0.3不等于2.2???

double a=1.9; 6k l3v+G1x*_:A(}!V
double b=0.3; 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛8F-X8P1i7^
double c=a+b;
4^0N:Z,t'y程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,黑客,安全,技术社区,技术论坛System.out.println(c); /G(|1}8t*C2Z7T!{7j4V }5K

*f/K)X2f(e!n&vTechWeb-技术社区输出结果却不是2.2,是2.1999999999997
/c){1@#t!\6H4N7B!R/@到底是怎么回事呀?

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:54
float和double类型的主要设计目标是为了科学计算和工程计算。它们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。float和double类型对于货币计算尤为不合适,因为要让一个float或者double精确地表达0.1(或者10的任何其他负数次方值)是不可能的。
要想得到精确结果,用BigDecimal,int或者long进行计算。
摘自 < <Effective Java>>

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:54
double本身的精度问题。

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:54
用BigDecimal 这个是精确计算!比如:在工资什么上面!

我这里有一个例子做了下!

import java.math.BigDecimal;

public class BigDecimalDemo {

public static void main(String[] args) {
BigDecimal b1 = new BigDecimal(Double.toString(3.056));
BigDecimal b2 = new BigDecimal(Double.toString(1.056));
System.out.println(b1.add(b2).doubleValue());
}

}
它里面有常用的+-*/ <%>remainder:

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:57
原因就是,浮点数是不能准确表示的。他有精度损失。所以出现这个结果
比如 2.0/7.0 这个不可能准确表示。加法也一样。


用BigDecimal 可以,不过进行除法运算时,也要注意精度,否则会溢出。

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:59
嗯,是double的精度问题。个人意见,你可以考虑用BigDecimal,或者,将两个数字同时扩大相同的倍数,将小数点移除掉。然后结果再除回来。推荐你看看Java解惑。

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:59
因为二进制无法精确表示浮点小数的小数部分,所以只能取近似值,而bigdecimal是一个java类,不单是一个简单类型,用它的方法可以做到更精确的计算

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:59
嗯  精度计算用BigDecimal

引用 回复 顶部
游客
未注册









发表于 2008-9-17 13:59
double和float都会丢失有丢失精度的问题。但是有种情况要注意,当两个数小数点后的值为0或者5时(如4.0,4.5)他的结果是准确的

引用 回复 顶部
游客
未注册









发表于 2008-9-17 14:00
计算机是用二进制表达一个数字的,它总之是不能表达一个足够精确的数,毕竟她有位数限制。

引用 回复 顶部
查看积分策略说明快速回复主题
选项 标题 Smilies
禁用 URL 识别
禁用 Smilies
禁用 Discuz!代码
使用匿名发帖
使用个人签名
接收新回复邮件通知
内容





当前时区 GMT+8, 现在时间是 2008-11-23 08:43
京ICP证060517号

本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.5.0 © 2001-2008 Comsenz Inc.
Processed in 0.021210 second(s), 7 queries

清除 Cookies - 联系我们 - TechWeb.com.cn - Archiver - WAP