java避免出现科学计数法表示_Java中的浮点数-科学计数法-加减乘除

上次,提到“元转分”这个浮点数问题,boss倾向于手动把1.23元这种格式,转换成123分。

但实际上,浮点数很容易遇到精度问题。

比如,System.out.println(4.015 * 1000);结果就不会是4015。

以前,总结的元转分的问题,没能考虑到所有的场景,今天补充点上次遗漏的。

-5.09,如果金额是负数,应该是-500-9=-509,而不是-500+9=-441,这是上次的一个超级bug。

另外,需要还有一个超级bug,“1045189788”转换成double类型的元时,结果变成了1.04。

debug了好久,才发现以前代码的漏洞。

1045189788这种比较大的浮点数,在传递过程中,是“科学计数法”表示的,类似“1.04E”,

所以,最后转换出了问题。

其实,我一直不建议boss采用这种人工截取计算的方式,需要考虑的场景太复杂,建议使用JDK内置的BigDecimal。

经过实践,发现很不错。

可以用double、string等多种原始类型,构造BigDecimal,再进行四则运算。

使用BigDecimal的关键是,控制“标度”即“精度”,scale。

算术运算结果的首选标度  运算 结果的首选标度

加 max(addend.scale(), augend.scale())

减 max(minuend.scale(), subtrahend.scale())

乘 multiplier.scale() + multiplicand.scale()

除 dividend.scale() - divisor.scale()

下面这个工具类,是从网上copy的,还是非常有价值的。

import java.math.BigDecimal;

/**

* 消除加减乘除的精度,解决Float与Double类型进度不准确的问题.

*/

public class DoubleUtil {

/**

* 加法运算

*

* @param v1

* @param v2

* @return

*/

public static double add(double v1, double v2) {

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

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

return b1.add(b2).doubleValue();

}

/**

* 减法运算

*

* @param v1

* @param v2

* @return

*/

public static double sub(double v1, double v2) {

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

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

return b1.subtract(b2).doubleValue();

}

/**

* 乘法运算

*

* @param v1

* @param v2

* @return

*/

public static double mul(double v1, double v2) {

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

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

return b1.multiply(b2).doubleValue();

}

/**

* 除法运算

*

* @param v1

*            被除数

* @param v2

*            除数

* @return 商

*/

public static double div(double v1, double v2) {

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

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

return b1.divide(b2).doubleValue();

}

/**

* 除法运算

*

* @param v1

*            被除数

* @param v2

*            除数

* @return 商和余数

*/

public static BigDecimal[] divideAndRemainder(double v1, double v2) {

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

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

BigDecimal[] arr = b1.divideAndRemainder(b2);

return arr;

}

/**

* 求商(向下舍入)

*

* @param v1

* @param v2

* @return

*/

public static BigDecimal divideToIntegralValue(double v1, double v2) {

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

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

System.out.println("------------");

return b1.divideToIntegralValue(b2);

}

public static void main(String[] args) {

testUnPrecision();

System.out.println("----------使用BigDecimal消除精度影响------------\n"

+ DoubleUtil.add(0.05, 0.01));

System.out.println(DoubleUtil.sub(1.0, 0.54));

System.out.println(DoubleUtil.mul(4.015, 1000));

System.out.println(DoubleUtil.div(12.3, 10));

// 得到商和余数

BigDecimal[] arr = DoubleUtil.divideAndRemainder(12.3, 10);

System.out.println("得到商和余数");

for (BigDecimal bigDecimal : arr) {

System.out.println(bigDecimal);

}

System.out.println(DoubleUtil.divideToIntegralValue(4.5, 2));

}

/**

* 不准确问题示例

*/

private static void testUnPrecision() {

System.out.println("--------Java自身的Double类型有精度损失----------");

System.out.println(0.05 + 0.01);

System.out.println(1.0 - 0.54);

System.out.println(4.015 * 1000);

System.out.println(12.3 / 100);

}

}

Java中怎么把科学计数法显示出全部数字

如果想去除科学计数法显示可以用如下方法处理: /** * 把科学计数法显示出全部数字 * @param d */ public static String object2Str(Object d) { ...

把Excel作为数据库,读到DataTable中,Excel科学计数法数字转字符串

需要引用:using System.Data.OleDb; /// /// 获取Excel数据,包含所有sheet /// /// & ...

将Excel中读取的科学计数法表示的Double数据转换为对应的字符串

已在SegmentFault提问,目前没有答案,自行实现如下: private static String getRealNumOfScientificNotation(String doubleSt ...

Java 科学计数法

目录 Java 科学计数法 1 科学计数法的概念 1.1 有效数字 1.2 E记号 2 Java中的科学计数法 2.1 NumberFormat 2.2 DecimalFormat 2.3 BigDe ...

数据库字段出现科学计数法e+的情况分析

问题: 有时候,我们在将excel表格中数据导入数据库中时,对于表格中的数字会默认为float的数据类型,这个时候导入到数据库中的这个表的值是正常显示的: 然而如果你要把导入到数据库中的表,再插入到另 ...

解决从Excel导入数据库,导入到DataTable时数据类型发生变化的问题(如数字类型变成科学计数法,百分数变成小数)

做项目的时候,C#读取Excel数据到DataTable或者DataSet,设断点查看DataTable,发现Excel的显示为较长位数数字的字段如0.000012在DataTable中显示为科学计数 ...

如何使java中double类型不以科学计数法表示

在java中,把一个double或者BigDecimal的小数转换为字符串时,经常会用科学计数法表示,而我们一般不想使用科学计数法,可以通过:DecimalFormat a = new Decimal ...

Java将Excel中科学计数法解析成数字

需要注意的是一般的科学表达式是1.8E12 1.8E-12 而在Excel中的科学表达式是1.8E+12 1.8E-12 我写的科学计数法的正则表达式是(-?\d+\.?\d*)[Ee]{1}[\+- ...

java使用poi解析或处理excel的时候,如何防止数字变成科学计数法的形式和其他常见Excel中数据转换问题

当使用POI处理excel的时候,遇到了比较长的数字,虽然excel里面设置该单元格是文本类型的,但是POI的cell的类型就会变成数字类型. 而且无论数字是否小数,使用cell.getNumberi ...

随机推荐

review again and again

盲评结果出来了.然而对于我并没有太大的影响.从头到尾我没有紧张过,自然也不会有如释重负的感觉. 昨天说了事情要提前做准备.早上,到教研室挺早,review的时候,发现论文中一个关于目录的小问题,解决掉 ...

INNODB自增主键的一些问题

背景: 自增长是一个很常见的数据属性,在MySQL中大家都很愿意让自增长属性的字段当一个主键.特别是InnoDB,因为InnoDB的聚集索引的特性,使用自增长属性的字段当主键性能更好,这里要说明下自增 ...

Java代码实现excel数据导入到Oracle

1.首先需要两个jar包jxl.jar,ojdbc.jar(注意版本,版本不合适会报版本错误)2.代码: Java代码   import java.io.File; import java.io.Fi ...

[LintCode] Maximal Square 最大正方形

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...

winform最小化后隐藏到右下角,单击或双击后恢复 .

01.//先拖一个notifyIcon控件进来 02. 03.//然后在您的notifyIcon控件中添加 MouseDoubleClick事件,代码如下 04. 05. private void n ...

EditorWindow 和MenuItem

using UnityEngine; using System.Collections; using UnityEditor; public class ClipEventEditor : Edito ...

第三方框架FMDB

摘要:关键点:创建.插入.查询.数据格式化 第三方框架FMDB -------------------------------------------------------------------- ...

如何在Gulp中提高Browserify的打包速度

使用Browserify打包js时如果项目变得越来越大,编译时间就会相应变得越来越长.使用官方的插件watchify是个比较有效的提高速度方案. 提速原理 watchify的用法和gulp的watch ...

Wcf host

Uri baseAddress = new Uri(uri);//var binding = new WebHttpBinding(WebHttpSecurityMode.None); var bas ...

Address already in use : connect 的解决办法

最近做百万次通讯测试,在做并发测试时发现eclipse的控制台输出超过10万条信息时开始有报错内容 Address already in use : connect 这种错误多了后紧接着eclipse ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值