This discussion is archived
6 Replies Latest reply: Nov 16, 2007 2:57 PM by 807603 RSS

Determine number of decimal places? - BigDecimal.scale() doesn't make sense

807603 Newbie
Currently Being Moderated
Hi all,
I'm trying to determine the number of decimal places in a double. In my case, I want to make sure that the number has no more than 4 decimal places.


I have tried something like

double aDouble
String str = Double.valueOf(aDouble).toString();
str = str.substring(w1Str.indexOf(".") + 1);

if(str.length() > 4)
//throw error

This approach works fine as long as the Double.toString() doesn't return a number in scientific notation.

I've looked and haven't found a very good solution so far, so any suggestions would be welcome.

I've tried to use BigDecimal.scale() to determine the number of decimal places in a number, but I have found for 0.35 that its scale is 53!! Granted, I haven't used BigDecimal very much, but per the BigDecimal API, it should return a scale() of 2. This is definitely the case for 0.25, but I don't understand why it is 53 for 0.35. Any explanation would be welcomed, but not necessary.

Thanks,
Jim
  • 1. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make sense
    807603 Newbie
    Currently Being Moderated
    The big mistake the uninitiated make is confusing number display with number storage.
    If you are talking about restricting the display of the double to 4 decimal places then:
    http://java.sun.com/javase/6/docs/api/java/text/DecimalFormat.html
  • 2. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make s
    807603 Newbie
    Currently Being Moderated
    I simply want to make sure the number entered by a user didn't have more than four decimal places. I think I see where you're coming from with regards to number storage.

    Jim
  • 3. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make s
    807603 Newbie
    Currently Being Moderated
    the number entered by a user
    Your substring method would work fine.
    I dont see why youre working with a Double? The user had to enter the number as a String right?
    So unless you allow your users to use scientific notation... (hint: convert to double AFTER)

    Another (sloppy way) would be to shift the decimal, use floor(), and then shift back.
  • 4. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make sense
    807603 Newbie
    Currently Being Moderated
    And I should have said this earlier, if youre using doubles then this requirement is ridiculous anyway. You could enter ".1234" and end up with ".123300000009" (not quite but something
    like that).

    Why? doubles are 64 bits with a potential for 1.8...e19 states and yet they attempt to represent
    values from 4.9...e-324d to 1.7...e+308d.
  • 5. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make s
    807603 Newbie
    Currently Being Moderated
    Hi TuringPest,
    Thanks for your quick responses and feedback. I'm using a Struts form bean and having Struts hand me a double to use in my code.

    I ended up using the DecimalFormat class:

    private boolean checkDecimalPlaces(double wf) {
    DecimalFormat df = new DecimalFormat("#.######");
    String format = df.format(wf);
    format = format.substring(format.indexOf(".") + 1);

    return format.length() > 4;
    }

    I used 6 #'s to be able to check for additional decimal places and then performed the check.

    Thanks,
    Jim
  • 6. Re: Determine number of decimal places? - BigDecimal.scale() doesn't make s
    807603 Newbie
    Currently Being Moderated
    Jim,
    Your code doesnt work.
    if i enter .1234009999999 your test passes (because its truncating after 6 places).

    Consider using my method:
         return d > (Math.floor(d * 10000) / 10000);
    Though with the finnickiness of floating point numbers...

    This requirement with doubles is a little silly.
    A more accurate approach might be a hybrid of both our ideas.

    roughly:
    return d > Double.parseDouble(("" + d).substring(0, decimalIndex + 5))
    import java.text.*;
    
    public class NumberTester{
    
    public static void main(String[] args){
    
         System.out.println("test 1: " + NumberTester.test2(0.123400001));
         System.out.println("test 2: " + NumberTester.test2(0.12345));
    
    }
    
    public static boolean test(double d){
    
         return d > (Math.floor(d * 10000) / 10000);
    
    }
    
    public static boolean test2(double wf) {
    
         DecimalFormat df = new DecimalFormat("#.######");
         String format = df.format(wf);
         System.out.println("format: " + format);
         format = format.substring(format.indexOf(".") + 1);
    
         return format.length() > 4;
    
    }
    
    }