java如何获取一个double的小数位数

前言

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

方法分析

当前能想到的比较容易有下面几种
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

原文地址:https://www.cnblogs.com/linkstar/p/8955779.html

时间: 2024-10-02 23:36:50

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

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

此小工具类主要用于数值四舍五入.数值格式化输出,很简单,若想深入研究,敬请自行查阅 BigDecimal 或 DecimalFormat 的 API,BigDecimal.setScale(位数,四舍五入法)中四舍五入法有如下 7 种: 1. ROUND_UP:远离零方向舍入.向绝对值最大的方向舍入,只要舍弃位非0即进位. 2. ROUND_DOWN:趋向零方向舍入.向绝对值最小的方向输入,所有的位都要舍弃,不存在进位情况. 3. ROUND_CEILING:向正无穷方向舍入.向正最大方向靠拢.

【java解惑】使用double进行小数运算

如下代码: public class Example002 { public static void main(String args[]) { System.out.println("println:( 2.00 - 1.10) = " + (2.00 - 1.10)); System.out.printf("printf:( 2.00 - 1.10) = %.2f%n", 2.00 - 1.10); System.out.println("BigDec

Double 判断小数位数

Double Float类型 判断小数位数存在的问题: Double Float 类型在 数值超过1千万直接转换为字符串 会采用 "科学计数法" 所以采用将Double转为字符串再转为BigDecimal 再转为字符串的方法可以获取原来的形式 所以获取小数位数的方法为: public int checkIsDoublePointTwo(Double param) { if (param == null) { return 0; } BigDecimal bd = new BigDeci

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

package com.readfile; import java.io.File; public class GetAllFiles { public static void main(String[] args) { //路径 这里写一个路径进去 String path="F:\\QQ文档"; //调用方法 getFiles(path); } /** * 递归获取某路径下的所有文件,文件夹,并输出 */ public static void getFiles(String path

java中获取所有文件--(递归调用)

import java.io.File;import java.io.*; //获取一个文件夹中的所有的文件.  /*    打印要求:      -- a.txt   -- IO.doc      -- ~$IO.doc   -- 代码   -- --.metadata   -- --Day18   --视频   -- --01 线程通信.wmv   -- --02 守护线程和join方法.wmv   -- --03 Filed的创建.wmv   -- --04 File的常用方法.wmv  

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

http://blog.csdn.net/yuhua3272004/article/details/3075436 使用java.math.BigDecimal工具类实现 java保留两位小数问题: 方式一(四舍五入形式保留两位小数,注意模式ROUND_HALF_UP): 四舍五入   double   f   =   111231.5585;   BigDecimal   b   =   new   BigDecimal(f);   double   f1   =   b.setScale(2

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

1:计算double值四舍五入的方法 对小数数值进行四舍五入,首先应该确认保留小数位, 如果数值的小数精度大于保留小数位,那么开始四舍五入计算.四舍五入的方法非常简单,在所有要丢失精度的小数位中加5,如果大于10则向前进位,最后计算出四舍五入的结果. /// <summary>计算double值四舍五入的方法 /// /// </summary> /// <param name="dbl">进行四舍五入的数值</param> /// &l

Java中如何判断一个double类型的数据为0?

Java中如何判断一个double类型的数据为0 其实这个问题很简单,只是很多时候考虑复杂了,直接用==判断即可.下面给出测试例子: /**  * 如何判断一个double类型的数据为0  *  * @author leizhimin 2014/8/27 10:31  */ public class Test4 {     public static void main(String[] args) {         double x = 0.00000000000000000;       

java进阶之反射:反射基础之如何获取一个类以及如何获取这个类的所有属性和方法(1)

java学习一段时间之后,大家可能经常会听到反射这个词,那么说明java已经学习到一个高一点的层次了.接下来我会一步步和大家一起揭开java高级特性反射的神秘面纱. 首先介绍下类对象这个概念,可能会经常用到这个概念: 类对象:java中有句很经典的话"万事万物皆对象",相信大家都不陌生,这句话告诉了我们java的特征之一,那就是面向对象.java中类的概念我们都很熟悉,既然万事万物皆是对象,那么类是谁的对象呢?<对象的概念:一个类的实例>换句话说,类是谁的实例.如此就有了类