前言

看标题是不是觉得这是一个很简单的问题,我一开始也是这么认为的,但是实际情况下,在各种情况下我们都进行了测试,发现很多实际情况是无法不尽如人意的。

方法分析

当前能想到的比较容易有下面几种
1、直接使用double处理
2、将double转换成String进行处理

方法一:直接对double进行处理,进行计算通过计算后的结果进行取模操作获取小数位数,如下:

    public static int getNumberDecimalDigits(double number) {
if (number == (long)number) {
return 0;
}
int i = 0;
while (true){
i++;
if (number * Math.pow(10, i) % 1 == 0) {
return i;
}
}
}

方法二:将double转换成String后,然后利用“.”分割进行判断,如下:(这里double转换String有多种方式这里我们选择其中的一种)

public static int getNumberDecimalDigits(double number) {
String moneyStr = String.valueOf(number);
String[] num = moneyStr.split("\\.");
if (num.length == 2) {
for (;;){
if (num[1].endsWith("0")) {
num[1] = num[1].substring(0, num[1].length() - 1);
}else {
break;
}
}
return num[1].length();
}else {
return 0;
}
}

测试方法:

public static void main(String[] args) {
System.out.print(getNumberDecimalDigits(0));
System.out.print(" " + getNumberDecimalDigits(0.0));
System.out.print(" " + getNumberDecimalDigits(1));
System.out.print(" " + getNumberDecimalDigits(-11.1));
System.out.print(" " + getNumberDecimalDigits(1.01));
System.out.print(" " + getNumberDecimalDigits(0.0100));
System.out.print(" " + getNumberDecimalDigits(0.123456));
System.out.print(" " + getNumberDecimalDigits(11111111.1234));
System.out.print(" " + getNumberDecimalDigits(11.0123456789));
}

结果分析

测试结果:
方法一:0 0 0 1 2 2 6 5 11
方法二:0 0 0 1 2 2 6 13 10

为什么最后的结果和我们想象不一样呢???
原因有三个:
1、double计算丢失精度:
2.01 * 10 = 20.099999999999998

2、double转string丢失精度:
String.valueOf(11111111.1234) = 1.11111111234E7
11111111.1234 + "" = 1.11111111234E7
Double.valueOf(11111111.123) = 1.1111111123E7
...

总结

所以在当前情况下,只要使用double进行判断都会出现各种各样的问题,因为double精度的问题。
所以唯一能解决的办法就是,不要使用double,直接使用字符串,无论是从客户端传入的值还是生产的值都是直接使用字符串进行处理和判断,判断方法与方法二类似。
如果非要进行计算,请使用BigDecimal进行计算。new BigDecimal的时候注意一定要使用字符串作为参数进行new

如果你有更好的方法,能通过上面的测试,那赶紧评论让我膜拜膜拜~

国外问题提出和解决:
https://stackoverflow.com/questions/6264576/number-of-decimal-digits-in-a-double?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

java如何获取一个double的小数位数的更多相关文章

  1. Java实现获取一个随机的两位数

    import java.util.Random; //获取一个随机的 两位数public class getrandomdouble { public static void main(String[ ...

  2. Java学习-047-数值格式化及小数位数四舍五入

    此小工具类主要用于数值四舍五入.数值格式化输出,很简单,若想深入研究,敬请自行查阅 BigDecimal 或 DecimalFormat 的 API,BigDecimal.setScale(位数,四舍 ...

  3. java 获取一个整数的各个位数

    两种方法~  第一种是取模运算  第二种是使用char数组进行分割开依次存到数组[推荐第二种] 获取一个四位数的各个位数 int qian =input/1000; //千位除以1000       ...

  4. Java 递归获取一个路径下的所有文件,文件夹名称

    package com.readfile; import java.io.File; public class GetAllFiles { public static void main(String ...

  5. java 递归获取一个目录下的所有文件路径

    还是日志的问题,log4j生成的日志文件,自动保存到月份所在的文件夹中,需要获取到所有的日志文件,包括文件夹 private List<String> ergodic(File file, ...

  6. JAVA如何把一个float四舍五入到小数点后2位,4位,或者其它指定位数.

    怎么使float保留两位小数或多位小数 http://meryvn.blog.163.com/blog/static/36962664201173010402629/ 两种方法: import   j ...

  7. java实验三——求平均数,数组排序(有关java保留小数位数,由于编译器版本未到1.5导致的报错format函数第二个参数不对,要求是Object[])

    package hello; import java.util.Arrays; public class 实验三更正版 { public static void main(String[] args) ...

  8. java.math.BigDecimal保留两位小数,保留小数,精确位数

    http://blog.csdn.net/yuhua3272004/article/details/3075436 使用java.math.BigDecimal工具类实现   java保留两位小数问题 ...

  9. double四舍五入,商品金额大小写转换,设置货币的小数位数跟格式输出,进制转化

      1:计算double值四舍五入的方法 对小数数值进行四舍五入,首先应该确认保留小数位, 如果数值的小数精度大于保留小数位,那么开始四舍五入计算.四舍五入的方法非常简单,在所有要丢失精度的小数位中加 ...

随机推荐

  1. (摘录)String是值传递还是引用传递

    String应该是一个封装类型,它应该是引用传递,是可以改变值的, 运行的结果应该是”cd”.我们实际运行一下看看, str=ab,这如何解释呢?难道String是基本类型?也说不通呀. 这就要从ja ...

  2. Layui使用table展示数据

    今天在Layui官网拿了一个table表格数据展示的源码,研究遇到了很多问题,最后才把数据展示出来,和大家分享下. 源码地址:https://www.layui.com/demo/table/oper ...

  3. Python Day 7

    阅读目录 内容回顾: 数据类型相互转换: 字符编码: ##内容回顾 #1.深浅拷贝 ls = [1, 'a', [10]] 值拷贝:直接赋值 ls1 = ls, ls中的任何值发生改变,ls1中的值都 ...

  4. 1004 Counting Leaves 对于树的存储方式的回顾

    一种新的不使用左右子树递归进行树高计算的方法,使用层次遍历 树的存储方式: 1.本题提供的一种思路: 使用(邻接表的思想)二维数组(vector[n])表示树,横坐标表示 父节点,每一行表示孩子. 能 ...

  5. Solaris:你好奇的十件事

    想想你周围的人,看看他们正在使用的操作系统.绝大部分人的电脑都在用主流操作系统:Windows,MacOS,甚至是Ubuntu.当说到Solaris,Unix和BSD的时候,其他人还以为你说鸟语呢.除 ...

  6. Runnable与Callable区别

    相同点: 两者都是接口:(废话) 两者都可用来编写多线程程序: 两者都需要调用Thread.start()启动线程: 不同点: 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果:而 ...

  7. android 界面设计

    wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetric ...

  8. xpath爬取新浪天气

    参考资料: http://cuiqingcai.com/1052.html http://cuiqingcai.com/2621.html http://www.cnblogs.com/jixin/p ...

  9. Smokeping安装部署

    稳定性检测工具smokeping安装配置和使用方法 Smokeping介绍 是对IDC网络质量,稳定性等最好的检测工具,包括常规的 ping,dig,echoping,curl等,可以监视www服务器 ...

  10. Javascript高级编程学习笔记(56)—— DOM2和DOM3(8)低版本IE范围

    虽然IE9支持了DOM范围,但是IE8及更早版本并不支持DOM范围 所以IE8以下的更早版本的IE提出了与之类似的概念以供大家使用 也就是 文本范围 var range = document.body ...