python科学计算数据应用(第2版)

156.4元

(需用券)

去购买 >

1. 踩坑经历

上周,一个用户反馈他创建的某个销售单无法打开,但其余销售单都可以正常打开,当时查看了生产环境的ERROR日志,发现抛了这样的异常:java.lang.NumberFormatException: For input string: "E"。

相信大家对这个异常都不陌生,很显然,是因为将字符串转换为数字时抛出的,比如下面这样:

但仔细查看了用户报错的单据,也没有发现哪里有输入“E”这样的字符串(请原谅我第一时间没有想到是科学计数法造成的,哈哈),最后把生产环境的这条数据插入到了开发环境中,定位到原来是因为将金额转换为大写时导致的,报错的关键代码如下所示:

String totalAmountStr = String.valueOf(totalAmount / 100.0);

String amountCN = MoneyUtils.toChinese(totalAmountStr);

其中totalAmount是一个long类型的变量,之所以除以100.0,是因为我们数据库中存储金额都是按分为单位存储的(相信很多小伙伴也是这么存储的),第2行代码主要是为了将金额转换为大写,比如将105000.50转换为壹拾万零伍仟元伍角。

用户报错的那个单据,totalAmount为2700万,转换为分就是:2700000000,执行完totalAmount / 100.0,输出结果竟然是2.7E7,而不是预期的27000000,因此导致了异常:java.lang.NumberFormatException: For input string: "E"。

最后的解决方案是将金额转换为BigDecimal来处理,代码修改为如下所示:

String totalAmountStr = new BigDecimal(String.valueOf(totalAmount)).divide(new BigDecimal("100"),2, RoundingMode.HALF_UP).toString();

String amountCN = MoneyUtils.toChinese(totalAmountStr);

2. 原因分析

在Java中,当浮点数(float、double)的整数部分达到8位及以上,会以科学计数法表示,如下所示:

double firstAmount = 2700000D;

double secondAmount = 27000000D;

double thirdAmount = 2700000.25D;

double fourthAmount = 27000000.25D;

System.out.println(firstAmount);

System.out.println(secondAmount);

System.out.println(thirdAmount);

System.out.println(fourthAmount);

默默数了下,整数部分8位的话,都是千万级别了,估计遇到这个问题的用户很豪,哈哈。

所以使用double来表示金额,当金额遇到科学计数法时,就会显示不正常、甚至造成一些意想不到的异常。

3. 解决方案

如果不想用科学计数法显示,而是显示金额本身,有以下2种解决方案:

使用NumberFormat

使用BigDecimal

3.1 方案一:使用NumberFormat

使用NumberFormat的方法如下所示:

NumberFormat numberFormat = NumberFormat.getInstance();

numberFormat.setGroupingUsed(false);

double secondAmount = 27000000D;

double fourthAmount = 27000000.25D;

System.out.println(numberFormat.format(secondAmount));

System.out.println(numberFormat.format(fourthAmount));

当将numberFormat.setGroupingUsed(false);注释掉或者修改为numberFormat.setGroupingUsed(true);时,输出结果就变为了:

3.2 方案二:使用BigDecimal(推荐)

使用BigDecimal的方法如下所示:

double secondAmount = 27000000D;

double fourthAmount = 27000000.25D;

System.out.println(new BigDecimal(String.valueOf(secondAmount)).setScale(2,RoundingMode.HALF_UP).toString());

System.out.println(new BigDecimal(String.valueOf(fourthAmount)).setScale(2,RoundingMode.HALF_UP).toString());

相比而言,我更推荐使用BigDecimal的这种方案。

关于BigDecimal的更多用法,可以查看我写的另一篇博客:Java BigDecimal使用指南。

java 11官方入门(第8版)教材

79.84元

包邮

(需用券)

去购买 >

java数字转大写 其他报异常_【踩坑系列】使用long类型处理金额,科学计数法导致金额转大写异常...相关推荐

  1. JAVA科学计数法,金额数字,转换为中文大写字

    网上看到别人的代码,觉得很好,收藏下来 网上其他人的代码大多是只能转换整数最多13位,一般转换方案都是下面两种(第一种看完都不想再当码农了,第二种看似挺好, 但是处理起来截取字符串麻烦,容易因规则太复 ...

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

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

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

    http://vincentboy.iteye.com/blog/1647187 问题:在java中,怎样把一个double数转换为字符串时,不用科学计数法表示. 解决方法1: //对Double类型 ...

  4. python科学计数法转换_柳小白Python学习笔记35 Excel之科学计数法类型转换及数据选取1...

    昨天学习了使用pandas模块如何查看Excel工作表"wz"的基本信息.今天学习,转换数字科学计数法格式及提取需要处理的数据,接下来就进入今天的学习吧. 一.转换科学计数法格式 ...

  5. 用JavaScript实现列数据的标出重复项和去重(解决科学计数法的excel数据去重异常问题)

    是这样,通常情况下标出重复项和去重复项这种比较简单的工作交给excel就可以了,但是excel有时候会出现无法处理的情况,比如说一串数字太长,会自动用科学计数法来表示,这个时候如果标出重复项就会出现乱 ...

  6. java excel 电话号码_数值或者电话号码被EXCEL转成了科学计数法,用XSSFCell 如何读取...

    public static Map readXls() throws IOException { //用来获取每一个小号重复多次,被多少账号用了.来平均 58 agent 查询出来的数据. Map m ...

  7. Java 科学计数法

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

  8. php科学计数法转string,php如何将科学计数法转数字

    php将科学计数法转数字的实现方法:首先通过if语句判断指定的数值是否为科学计数法:然后提取科学计数法中有效的数据:接着正式处理该数据:最后调用"convert_scientific_num ...

  9. 科学数字_Excel分列时拒绝让超过15位的数字变成科学计数法

    分列时让超过15位的数字不变成科学计数法 Excel情报局 生产搬运分享Excel基础技能 Excel知识青年 用1%的Excel基础搞定99%的日常工作 做一个有文艺范的Excel公众号 Excel ...

最新文章

  1. 数据结构与算法(3-1)栈(顺序栈、两栈共享空间、链栈、栈的计算器)
  2. 【机器学习入门】(7) 线性回归算法:原理、公式推导、损失函数、似然函数、梯度下降
  3. 为什么结构主机和全局编录服务器不能放在同一个域控制器上?
  4. [原创]TimeQuest约束外设之诡异的Create Generated Clocks用法
  5. POJ 1061 青蛙的约会(扩展欧几里得)
  6. Axios——Axios封装DEMO
  7. 在linux中安装.sh 文件
  8. js基础---数组方法
  9. SQL 死锁分析(转贴)
  10. springmvc与Servlet3.0不依赖common包实现文件上传
  11. 如何转换并压缩png格式图片
  12. POJO中使用ThreadLocal实现Java嵌套事务
  13. Kubernetes对象之Replication Controller(RC)和Replica Sets(RS)
  14. 用vmware workstation做双机集群的详细过程(三)
  15. C语言-第19课 - #pragma预处理分析
  16. 自己如何选购更换内存条?(超详细)
  17. 测试图片色域软件,显示器色域检测
  18. xdg在Linux中的用法,linux-如何使用sudo获取XDG变量?
  19. flac编码音频转alac编码(使用ffmpeg)
  20. ASP.NET MVC5+EF6+EasyUI 后台管理系统(53)-工作流设计-我的批阅

热门文章

  1. 28、Power Query-分支语句的妙用
  2. 统计内表行数常用的三种方法
  3. 基本概念/MM相关概念
  4. IDOCALE常用tcode
  5. ABAP日期操作函数
  6. 货拉拉周胜馥,这次赌“输”了?
  7. python mulit函数_python – 将函数应用于MultiIndex pandas.DataFrame列
  8. 做折线图的软件_三星Galaxy Labs,它由4个下层软件构成,各有其用
  9. 一个页面区分管理者和普通用户如何设计_如何从「百度知道」中删除 bai du zhi dao?...
  10. |9 其他(linux特定的), 用来存放内核例行程序的文档.,Linux下的帮助命令