- 浏览: 221281 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
ranweizheng:
亲,第二个方法,应该是 i<ary.length-1 吧 ...
JS判断一个数组中是否有重复值的三种方法 -
liuzhenxingwinword:
spring线程池配置 -
flw521521:
好写法,赞
jquery 去除所有文本框输入值的前后空格 -
814687491:
数据查询出来后,如果你删除了其它几条数据人,我在不重新刷新页面 ...
jQuery Pagination 整理 -
D_ZLong:
...
IE与firefox兼容问题
[1] 精确的浮点运算:
在Java里面,有时候为了保证数值的准确性需要精确的数据,先提供一个例子就可以发现问题了:
按照我们的期待,上边应该是什么结果呢,但是看输出我们就会发现问题了:
这样的话这个问题就相对严重了,如果我们使用123.3元交易,计算机却因为1.2329999999999999而拒绝了交易,岂不是和实际情况大相径庭。
[2] 四舍五入:
另外的一个计算问题,就是四舍五入。但是Java的计算本身是不能够支持四舍五入的,比如:
这个输出为:
401.49999999999994
所以就会发现这种情况并不能保证四舍五入,如果要四舍五入,只有一种方法
java.text.DecimalFormat:
上边代码输出为:
发现问题了么?因为DecimalFormat使用的舍入模式, 舍入模式 详情参见本文最后部分。
[3] 浮点输出:
Java浮点类型数值在大于9999999.0就自动转化成为科学计数法,看看下边的例子:
输出结果为:
但是有时候我们不需要科学计数法,而是转换成为字符串,所以这样可能会有点麻烦。
总结:
所以在项目当中,对于浮点类型以及大整数的运算 还是尽量不要用double,long等基本数据类型以及其包装类,还是用Java中提供的BigDecimal,BigInteger等大数值类型来代替吧。
但这里特别说明一下BigDecimal类的两个构造函数的区别,他们分别是:
new BigDecimal(String val ) 和 new BigDecimal(double val )
先看例子:
输出结果有一次令人意外了,同时两者之间的区别也一目了然了:
所以在 就是想利用double原始类型进行了相关计算之后再转成BigDecimal类型 的场合下,为了防止精度出现偏离,建议使用参数为String类型的该构造方法。即new BigDecimal(String val )。
BigDecimal舍入模式介绍:
舍入模式在java.math.RoundingMode 里面:
RoundingMode.CEILING :向正无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.UP;如果结果为负,则舍入行为类似于 RoundingMode.DOWN。注意,此舍入模式始终不会减少计算值
RoundingMode.DOWN :向零方向舍入的舍入模式。从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值
RoundingMode.FLOOR :向负无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.DOWN;如果结果为负,则舍入行为类似于 RoundingMode.UP。注意,此舍入模式始终不会增加计算值
RoundingMode.HALF_DOWN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN
RoundingMode.HALF_EVEN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同 RoundingMode.HALF_DOWN。注意,在重复进行一系列计算时,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。此舍入模式类似于 Java 中对 float 和 double 算法使用的舍入策略
RoundingMode.HALF_UP :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN。注意,此舍入模式就是通常学校里讲的四舍五入
RoundingMode.UNNECESSARY :用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。如果对生成精确结果的操作指定此舍入模式,则抛出 ArithmeticException
RoundingMode.UP :远离零方向舍入的舍入模式。始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值
这段代码的输出为:
源自:http://tidercreverse.group.iteye.com/group/topic/25085
在Java里面,有时候为了保证数值的准确性需要精确的数据,先提供一个例子就可以发现问题了:
public class FloatNumberTester { public static void main(String args[]){ System.out.println(0.05+0.01); System.out.println(1.0 - 0.42); System.out.println(4.015 * 100); System.out.println(123.3 / 100); } }
按照我们的期待,上边应该是什么结果呢,但是看输出我们就会发现问题了:
0.060000000000000005 0.5800000000000001 401.49999999999994 1.2329999999999999
这样的话这个问题就相对严重了,如果我们使用123.3元交易,计算机却因为1.2329999999999999而拒绝了交易,岂不是和实际情况大相径庭。
[2] 四舍五入:
另外的一个计算问题,就是四舍五入。但是Java的计算本身是不能够支持四舍五入的,比如:
public class GetThrowTester { public static void main(String args[]){ System.out.println(4.015 * 100.0); } }
这个输出为:
401.49999999999994
所以就会发现这种情况并不能保证四舍五入,如果要四舍五入,只有一种方法
java.text.DecimalFormat:
import java.text.DecimalFormat; public class NumberFormatMain { public static void main(String args[]){ System.out.println(new DecimalFormat("0.00").format(4.025)); System.out.println(new DecimalFormat("0.00").format(4.024)); } }
上边代码输出为:
4.02 4.02
发现问题了么?因为DecimalFormat使用的舍入模式, 舍入模式 详情参见本文最后部分。
[3] 浮点输出:
Java浮点类型数值在大于9999999.0就自动转化成为科学计数法,看看下边的例子:
public class FloatCounter { public static void main(String args[]){ System.out.println(9969999999.04); System.out.println(199999999.04); System.out.println(1000000011.01); System.out.println(9999999.04); } }
输出结果为:
9.96999999904E9 1.9999999904E8 1.00000001101E9 9999999.04
但是有时候我们不需要科学计数法,而是转换成为字符串,所以这样可能会有点麻烦。
总结:
所以在项目当中,对于浮点类型以及大整数的运算 还是尽量不要用double,long等基本数据类型以及其包装类,还是用Java中提供的BigDecimal,BigInteger等大数值类型来代替吧。
但这里特别说明一下BigDecimal类的两个构造函数的区别,他们分别是:
new BigDecimal(String val ) 和 new BigDecimal(double val )
先看例子:
public class BigDecimalMain { public static void main(String args[]){ System.out.println(new BigDecimal(123456789.01).toString()); System.out.println(new BigDecimal("123456789.01").toString()); } }
输出结果有一次令人意外了,同时两者之间的区别也一目了然了:
123456789.01000000536441802978515625 123456789.01
所以在 就是想利用double原始类型进行了相关计算之后再转成BigDecimal类型 的场合下,为了防止精度出现偏离,建议使用参数为String类型的该构造方法。即new BigDecimal(String val )。
BigDecimal舍入模式介绍:
舍入模式在java.math.RoundingMode 里面:
RoundingMode.CEILING :向正无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.UP;如果结果为负,则舍入行为类似于 RoundingMode.DOWN。注意,此舍入模式始终不会减少计算值
输入数字 | 使用CEILING舍入模式将数字舍入为一位数 |
5.5 | 6 |
2.5 | 3 |
1.1 | 2 |
1.0 | 1 |
-1.0 | -1 |
-1.1 | -1 |
-1.6 | -1 |
-2.5 | -2 |
-5.5 | -5 |
RoundingMode.DOWN :向零方向舍入的舍入模式。从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值
输入数字 | 使用DOWN舍入模式将数字舍入为一位数 |
5.5 | 5 |
2.5 | 2 |
1.1 | 1 |
-1.0 | -1 |
-1.6 | -1 |
-2.5 | -2 |
-5.5 | -5 |
RoundingMode.FLOOR :向负无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.DOWN;如果结果为负,则舍入行为类似于 RoundingMode.UP。注意,此舍入模式始终不会增加计算值
输入数字 | 使用FLOOR舍入模式将输入数字舍入为一位 |
5.5 | 5 |
2.3 | 2 |
1.6 | 1 |
1.0 | 1 |
-1.1 | -2 |
-2.5 | -3 |
-5.5 | -6 |
RoundingMode.HALF_DOWN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN
输入数字 | 使用HALF_DOWN输入模式舍入为一位 |
5.5 | 5 |
2.5 | 2 |
1.6 | 2 |
1.0 | 1 |
-1.1 | -1 |
-1.6 | -2 |
-2.5 | -2 |
-5.5 | -5 |
RoundingMode.HALF_EVEN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同 RoundingMode.HALF_DOWN。注意,在重复进行一系列计算时,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。此舍入模式类似于 Java 中对 float 和 double 算法使用的舍入策略
输入数字 | 使用HALF_EVEN舍入模式将输入舍为一位 |
5.5 | 6 |
2.5 | 2 |
1.6 | 2 |
1.1 | 1 |
-1.0 | -1 |
-1.6 | -2 |
-2.5 | -2 |
-5.5 | -6 |
RoundingMode.HALF_UP :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN。注意,此舍入模式就是通常学校里讲的四舍五入
输入数字 | 使用HALF_UP舍入模式舍入为一位数 |
5.5 | 6 |
2.5 | 3 |
1.6 | 2 |
1.0 | 1 |
-1.1 | -1 |
-1.6 | -2 |
-2.5 | -3 |
-5.5 | -6 |
RoundingMode.UNNECESSARY :用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。如果对生成精确结果的操作指定此舍入模式,则抛出 ArithmeticException
输入数字 | 使用UNNECESSARY模式 |
5.5 | 抛出 ArithmeticException |
2.5 | 抛出 ArithmeticException |
1.6 | 抛出 ArithmeticException |
1.0 | 1 |
-1.0 | -1.0 |
-1.1 | 抛出 ArithmeticException |
-1.6 | 抛出 ArithmeticException |
-2.5 | 抛出 ArithmeticException |
-5.5 | 抛出 ArithmeticException |
RoundingMode.UP :远离零方向舍入的舍入模式。始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值
输入数字 | 使用UP舍入模式将输入数字舍入为一位数 |
5.5 | 6 |
1.6 | 2 |
1.1 | 2 |
1.0 | 1 |
-1.1 | -2 |
-1.6 | -2 |
-2.5 | -3 |
-5.4 | -6 |
import java.math.BigDecimal; import java.text.DecimalFormat; /** *使用舍入模式的格式化操作 **/ public class DoubleFormat { public static void main(String args[]){ DoubleFormat format = new DoubleFormat(); System.out .println(format.doubleOutPut(12.345, 2)); System.out .println(format.roundNumber(12.335, 2)); } public String doubleOutPut(double v,Integer num){ if ( v == Double.valueOf(v).intValue()){ return Double.valueOf(v).intValue() + "" ; }else { BigDecimal b = new BigDecimal(Double.toString(v)); return b.setScale(num,BigDecimal.ROUND_HALF_UP ).toString(); } } public String roundNumber(double v,int num){ String fmtString = "0000000000000000" ; //16bit fmtString = num>0 ? "0." + fmtString.substring(0,num):"0" ; DecimalFormat dFormat = new DecimalFormat(fmtString); return dFormat.format(v); } }
这段代码的输出为:
12.35 12.34
源自:http://tidercreverse.group.iteye.com/group/topic/25085
发表评论
-
JDBCUtil
2013-06-07 22:38 0public class JDBCUtil{ pr ... -
luke
2013-01-17 09:41 0http://code.google.com/p/luke/ ... -
Apache commons-configuration
2012-11-15 16:47 1373Apache Commons-configuration ... -
Java、Js判断全角半角
2012-11-13 11:40 3292JS判断全角半角: function chkHalf(s ... -
HashMap实现原理
2012-10-23 21:49 10411.HashMap的数据结构 数组的特点是:寻址容易 ... -
Struts2 action返回值
2012-08-30 15:05 1230//设置调用完毕后 不处理result值 ActionC ... -
proxool
2012-06-06 17:23 1060Proxool连接池是sourceforge下的一个开源项目, ... -
图片上传压缩处理
2011-08-17 18:24 1307源自:http://www.iteye.com/topic/2 ... -
JSTL中fn函数的使用
2011-08-08 09:20 1196... -
OGNL表达式
2011-06-25 16:03 1683OGNL 表达式学习 (文章源自:http://w ... -
几种通信协议的比较
2011-06-24 11:15 1043文章源自:http://dalezhu.i ... -
jxl读写excel文件
2011-06-22 17:16 1091使用第三方工具包jxl来对excel进行读写操作 1.读取E ... -
分页实现的三种方式
2011-06-22 10:51 1890分页问题是一个非常普 ... -
自定义标签
2011-06-20 16:15 1299自定义标签: 1、实现自定义标签按如下步骤进行: (1 ... -
HttpConnection相关
2011-06-09 19:04 1638Java中可以使用HttpURLConne ... -
struts.properties
2011-05-28 16:10 1125struts.action.extension ... -
Spring配置数据源的三种方式
2011-05-04 10:35 1061Spring配置数据源的三种方式 1,使用org.spring ... -
tomcat 连接池泄露的问题:Cannot get a connection, pool exhausted
2011-05-04 10:25 49551 问题描述 Web程序在tomcat刚开始运行时速度很快,但 ... -
技术网站
2011-04-19 13:41 0第一个:[url]http://www.ite ... -
java获取IP地址
2011-03-18 15:40 1266public String getIpAddr(HttpS ...
相关推荐
然而,在某些情况下,我们可能需要将BigDecimal类型的值转换为Double类型,比如为了与一些只接受基本数据类型或其包装类的方法参数兼容,或者进行一些基于Double的数学运算等。本文将详细介绍如何在Java中实现...
### Java Double 精度问题总结 在Java编程语言中,`double` 类型是一种用于表示64位浮点数的原始数据类型。虽然 `double` 提供了相对较高的精度,但在涉及精确数学运算(特别是涉及到小数值)时,由于其内部采用二...
例如,在示例代码中,我们尝试将`double`类型的3215.10除以2,然后将其转换为`BigDecimal`对象,结果出现了精度缺失的问题。 首先,让我们分析一下代码: ```java public class Main { public static void main...
Java 中的双精度浮点数(double)类型在进行运算时经常出现精度丢失的问题,这是由于双精度浮点数在计算机内部的存储方式所致。双精度浮点数使用 64 位二进制数来存储小数,然而这种存储方式会导致某些小数无法精确...
`BigDecimal` 的出现就是为了解决这类问题。 #### 三、BigDecimal的基本操作 以下是一些常见的 `BigDecimal` 操作: 1. **加法**: 使用 `add()` 方法。 2. **减法**: 使用 `subtract()` 方法。 3. **乘法**: 使用...
然而,传入浮点数时需要注意,因为浮点数在Java中的表示可能存在精度损失,这可能导致创建的 `BigDecimal` 实例与预期的数值不完全匹配。 在进行相等比较时,`BigDecimal` 提供了 `equals()` 和 `compareTo()` 两个...
在 Java 中,浮点数的表示形式有多种,包括 float 和 double 等,但是这些类型在进行计算时会出现精度问题,而 BigDecimal 则可以解决这种问题。本文将主要介绍 Java 中的 BigDecimal 和 double 的示例及相关问题...
解决精度问题的方法有很多,如使用更高精度的数据类型(如Java中的`BigDecimal`),或者使用特定的算法进行浮点数比较。在进行浮点数计算时,可以设定一个容差值(epsilon),只要两个数的差的绝对值小于这个容差,...
要保证精度就要使用BigDecimal类,而且不能直接从double直接转BigDecimal,要将double转string再转BigDecimal。也就是不能使用BigDecimal(double val) 方法,你会发现没有效果。要使用BigDecimal(String val) 方法...
解决java数值范围以及float与double精度丢失的问题 Java中的数值范围和浮点数精度问题是许多开发者经常遇到的问题。下面我们将详细探讨Java中的数值范围、float和double类型的精度问题,并且提供解决方案。 一、...
标题中的"BigDecimal-CPP-master.zip"表明这是一个与BigDecimal类实现相关的C++项目压缩包。BigDecimal是一种可以处理任意精度的十进制浮点数的数据类型,它通常用于金融或会计等需要高精度计算的领域,因为在这些...
在BigDecimal工具类中,我们可以看到多个重载的方法,例如add方法和sub方法,这些方法可以根据不同的参数类型和精度需求进行选择。 首先,让我们来看一下add方法。add方法有三种重载形式,分别是add(double,double)...
* `BigDecimal(double)`: 创建一个具有参数所指定双精度值的对象。 * `BigDecimal(long)`: 创建一个具有参数所指定长整数值的对象。 * `BigDecimal(String)`: 创建一个具有参数所指定以字符串表示的数值的对象。 ...
在进行商业计算时,由于浮点数(double和float)存在精度问题,不能保证准确的结果,因此通常推荐使用BigDecimal来确保计算的精确性。本文将深入探讨BigDecimal的基本操作、应用场景及注意事项。 首先,创建...
初始化 BigDecimal 时,推荐使用字符串参数而非直接使用 double,因为 double 类型可能存在精度损失。例如: ```java BigDecimal num1 = new BigDecimal("0.005"); // 推荐 BigDecimal num2 = new BigDecimal...
- `BigDecimal.valueOf(double val)`:根据双精度浮点数创建一个 `BigDecimal` 实例。 ##### 3. 数学运算 `BigDecimal` 提供了一系列的方法来进行数学运算: - `add(BigDecimal augend)`:加法操作。 - `subtract...
### DecimalFormat精度解决与商业运算精度问题 在进行财务计算或者商业运算时,精度问题往往成为影响最终结果准确性的关键因素之一。特别是在Java这样的语言环境中,由于其内部采用二进制浮点数表示小数的方式,这...
2. 创建 BigDecimal 对象:可以通过多种方式创建 BigDecimal 对象,例如将 double 或 String 类型的数值转换为 BigDecimal 对象。 3. 精确的加法运算:使用 BigDecimal 的 add 方法可以进行精确的加法运算,例如将...
1. **高精度浮点数**:与`BigInteger`类似,`BigDecimal`适用于需要精确浮点数计算的场景,如财务和科学计算。它避免了双精度浮点数(`double`)可能出现的舍入误差。 2. **精度控制**:`BigDecimal`的精度可以通过...
双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是...