0

I have been trying to make a program to round doubles after decimal point- for example-4.45 will turn 4.50 and 3.23-3.20 and so on. for that I have tried to count how many numbers are after the decimal point them multiply it by 10 powered that number that I found add or deduct accordingly to make it round as a whole integer-for example 4.45 will first turn 445 then 450 then I divide it again by that number I found so I will end up with 4.50. what I did technically works, only problem I have is with counting the number of digits after the decimal point. for example I entered 20.13 as my double and I tried multiplying it by 10 until it is equal it's int-like if 201.3==201 otherwise I keep multiplying by 10. Only problem is it ruins my numbers in debug I saw it turned 20.13 to 201.299999998 instead of 201.3 and that makes my loop basically infinite and defeats the purpose altogether.
my function :

//input : The function gets a double number
//output : The function returns how many numbers are after the decimal point
public static int countDecimal(double num){
    int count=0;
    while(num!=(int)num){
        num*=10;
        count++;
    }
    return count;
}

Does anyone know why it's doing that and how do I achieve my purpose? I would also love to know if you know an easier way to round 4.45 to 4.5 because my way requires many other functions and is pretty long for something rather basic. The java function I saw only rounds to integers-4.5 to 5 for example.

Karoline
  • 125
  • 9
  • 1
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – AntonH Feb 26 '18 at 21:47
  • 1
    You can simply do, `Math.round(num * 100) / 100d;` – user2004685 Feb 26 '18 at 21:48
  • It might work if you use a `BigDecimal` instead of a `double`. – AntonH Feb 26 '18 at 21:48
  • 1
    The easiest way to do this is with strings. Find the last digit in the string. If it's 4 or less, just remove it. If it's 5 or more, remove it, and add 1 to the previous digit. Of course, when adding 1 to 9, you'll need to carry to the next digit. – user3386109 Feb 26 '18 at 21:49
  • thanks for all your suggestions the math.round works and I guess your right a String would be more efficient. By the way what is a BigDecimal and how do I use it instead of a double?it's not a type because it shows an error when I wrote it instead of a double. Sorry for my ignorance it's just that I'm kind of a newbie. – Karoline Feb 26 '18 at 21:56
  • Some info and links for BigDecimal: https://stackoverflow.com/tags/bigdecimal/info – user3386109 Feb 26 '18 at 22:01

3 Answers3

1

This is a very rough answer, but the idea is there.

Best thing to do is convert your number to a string

String numToString = String.valueOf(num);

Find the decimal's index and remove anything >2 of that

int decimalIndex = numToString.indexOf(".");
numToString = numToString.substring(decimalIndex, decimalIndex + 2);

Finally take your last number and round up or down accordingly.

Aliics
  • 129
  • 6
1

For a more generic solution dealing with only doubles...

public static double roundIt(double d, int places) {
        if (places < 0) throw new IllegalArgumentException("places must be >= 0");
        return Math.round(d * Math.pow(10, places)) / Math.pow(10, places);
}

Be wary of double overflow if entering a large number of "places" and rounding an already large number

Also, if you enter more places than the decimal originally had, it doesn't fill in the amount of places with 0's. I think you would have to use printf in order to get the extra 0's to print if you want that.

Jordan Cutler
  • 562
  • 4
  • 14
0

Java uses the IEEE 754 format to represent double (base-64) precision floating-point numbers. You can read about Java primitives here.

Basically, what this means is that doubles use 64 bits, one bit for the sign (positive or negative), 11 bits for the exponent, and 52 bits for the mantissa. You can figure out the number by multiplying the mantissa times 2^exponent, where the exponent can be negative, and then checking the sign bit for positive or negative. (It's a little more complicated than this, but that's the basic idea. You can check the IEEE 754 format here for the exact details)

All of the precision is stored in the mantissa, which is really just an integer, and since it uses binary, it can only precisely represent fractions where the denominator is a power of 2. This means there's no way to get a double that exact represents, say, 5.237, but you could use String.format() in Java to get a String representation rounded to a certain number of decimals places.

Charles Spencer
  • 626
  • 1
  • 6
  • 17