How to get the length of a numbers fraction part?

不打扰是莪最后的温柔 提交于 2019-12-13 14:27:27

问题


How do I find out the length or the number of digits of the fraction part of a decimal number?

I can see a few aproaches, e.g. with Strings like this one:

public static int getNumberOfFractionDigits(Number number) {
    Double fractionPart = number.doubleValue() - number.longValue();
    return fractionPart.toString().length() - 2;
}

But what is the best way to determine the length?

I could imagine some problems if I use Strings, e.g. because the locale and number format may be different from system to system. Is there a nice way to calculate it? Maybe without iteration?

Thanks in advance.


回答1:


I just wrote a simple method for this, hope it can help someone.

public static int getFractionDigitsCount(double d) {
    if (d >= 1) { //we only need the fraction digits
        d = d - (long) d;
    }
    if (d == 0) { //nothing to count
        return 0;
    }
    d *= 10; //shifts 1 digit to left
    int count = 1;
    while (d - (long) d != 0) { //keeps shifting until there are no more fractions
        d *= 10;
        count++;
    }
    return count;
}



回答2:


You may use java.text.NumberFormat.

nf = java.text.NumberFormat.getInstance (); 
// without BigDecimal, you will reach the limit far before 100  
nf.setMaximumFractionDigits (100);
String s = nf.format (number.doubleValue ())          

You may set the Decimal-Identifier as you like, and use regular expressions to cut off the leading part, and String.length () to evaluate the rest.




回答3:


Try this:

public static int getNumberOfFractionDigits(Number number) {
 if( number == null ) return 0; //or throw
 if( number.doubleValue() == 0.0d ) return 0;
 BigDecimal bd = new BigDecimal(number.toString()); 
 //BigDecimal bd = BigDecimal.valueOf(number.doubleValue()); // if double precision is ok, just note that you should use BigDecimal.valueOf(double) rather than new BigDecimal(double) due to precision bugs in the latter
 bd = bd.stripTrailingZeros(); //convert 1.00 to 1 -> scale will now be 0, except for 0.0 where this doesn't work
 return bd.scale();
} 

Edit:

If the number is actually an iteger (i.e. fraction of 0) this would still return 1. Thus you might check whether there actually is a fractional part first.

Edit2:

stripTrailingZeros() seems to do the trick, except for 0.0d. Updated the code accordingly.




回答4:


Looks like many offered the Big Decimal. It's easy on the eyes at least. The code shall work for ya.

package t1;

import java.math.*;

public class ScaleZ {
    private static final int MAX_PRECISION = 10;
    private static final MathContext mc = new MathContext(MAX_PRECISION, RoundingMode.HALF_EVEN);
    public static int getScale(double v){
        if (v!=v || v == Double.POSITIVE_INFINITY || v == Double.NEGATIVE_INFINITY)
            return 0;//throw exception or return any other stuff

        BigDecimal d = new BigDecimal(v, mc);
        return Math.max(0, d.stripTrailingZeros().scale());
    }


    public static void main(String[] args) {
        test(0.0);
        test(1000d);
        test(1d/3);
        test(Math.PI);
        test(1.244e7);
        test(1e11);
    }

    private static void test(double d) {
        System.out.printf("%20s digits %d%n", d, getScale(d));
    }
}



回答5:


That was my best implementation:

public class NumberHandler {

    private static NumberFormat formatter = NumberFormat.getInstance(Locale.ENGLISH);

    static {
        formatter.setMaximumFractionDigits(Integer.MAX_VALUE);
        formatter.setGroupingUsed(false);
    }

    public static int getFractionLength(double doubleNumber) {
        String numberStr = formatter.format(doubleNumber);
        int dotIndex = numberStr.indexOf(".");
        if (dotIndex < 0) {
            return 0;
        } else {
            return numberStr.length() - (dotIndex + 1);
        }
    }

}

Not effective, probably not perfect, but the other options was worse.




回答6:


public static int getNumberOfFractionDigits(double d) {
    String s = Double.toString(d), afterDecimal="";
    afterDecimal = s.subString(s.indexOf(".") + 1, s.length() - 1);
    return afterDecimal.length();
}


来源:https://stackoverflow.com/questions/5314954/how-to-get-the-length-of-a-numbers-fraction-part

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!