Win a copy of The Way of the Web Tester: A Beginner's Guide to Automating Tests this week in the Testing forum!

# format

kenneth ga
Greenhorn
Posts: 9
anybody could please explain why is it that System.out.println() when displaying a double rounds the value off or truncates the value?

say I have a code.

double d = 0.10000000000000000111512312578;
System.out.println(d);

the output is "0.1" and not the exact value?

in the JLS, it provides some explanation, but if I understood it corretly, it seems that there is not definite format whether to display as "0.1" or the exact "0.10000000000000000111512312578" as long as it is the closest value to the double value..

thanks.

Peter Chase
Ranch Hand
Posts: 1970
Forgive me if I'm wrong, but is the answer to this not that you are simply running out of precision in the "double"?

My understanding is that there are about 15 decimal digits of precision in a "double" and about 7 decimal digits of precision in a "float". Your number simply has too many zeros between the "tenths" and the rest of the number.

Julian Kennedy
Ranch Hand
Posts: 823
Bang on, Peter. (not an instruction! )
Use java.math.BigDecimal if you want more precision.

Jules

kenneth ga
Greenhorn
Posts: 9
thanks, you're probably right.

but, is there a rule in the toString(double) that says, the value will be rounded off when it's over the supported precision of "double"?

I can't find any or I could not understand what the Double.toString(double) really says about this one. Which I think is the one that is responsible in displaying the "double" string.

could anyone please spare some time for me on this one?

thanks.

Julian Kennedy
Ranch Hand
Posts: 823
I recently posted this in another thread:

That's the vagaries of floating point representation and arithmetic for you. The reason for the strangeness is that the internal representation is in binary. The sign, mantissa (bit before the 'E') and exponent (bit after the 'E') are split across the 32 bits of a float or the 64 bits of a double.

With only so many bits to work with there is a limit on the precision (number of significant figures, I suppose) that can be achieved. The more bits you have, the better the precision. Think about it. 1.1 in binary is 1.5 in decimal; 1.11 is 1.75; 1.111 is 1.875 and so on. Say you want to represent the decimal number 0.999 in binary: you can never do it exactly as 1.???1 in binary is always going to be 1.???5 in decimal.

Scary huh?! It's official that computers can't count, and they're running the systems that take care of your bank balance and keep the planes in the air!

Hope that's informative.

Does that shed any further light on it for you? As Peter said, there's no room in 64 bits (a double) for more than 15 digits of precision. The actual conversion to String and/or printing is irrelevant. The poor old double is left with no choice as she has eaten all the pies! (is full)

Jules

kenneth ga
Greenhorn
Posts: 9
i'm beginning to understand and the way seems clearer

however, i tried to look at the actual implementation of Double.toString(double) and in there, it manipulates the value of the "double" to be representable as "string". However, a double value of "0.1" which has no
actual decimal representation is being manipulated
to be representable in its closest value.
It just so happen that the implementation makes it
to "0.1" string. But the implementation can display
"0.02" or "0.234" as a representation of that double 0.1 value.

what i mean is, that it can represent any "string" value
since it is a string not an actual "double" value, the one
that is outputted by System.out.println().

I am understanding it right?

I hope you get my point.

thanks.

Julian Kennedy
Ranch Hand
Posts: 823
Sorry Kenneth, I don't really see what you're getting at. If the value in a double named point_one is 0.1D then why would Double.toString(point_one) return 0.02 or 0.234?

The moral of the story is that if you require very precise representations of floating point number then don't use float and double; use java.math.BigDecimal instead.

Jules

Peter Chase
Ranch Hand
Posts: 1970
While we're here, is it not true that Double.toString() is really only for debugging use?

If you are planning to put a floating-point number (float or double) in front of an end-user, you should carefully format it according to the needs of the application. The java.text.DecimalFormat class may help here.

One generally should not put the full number of digits in front of the user, either. This is because floating-point maths accumulates round-off errors, so one or more of the least-significant decimal digits are inaccurate and should not be displayed.

How many digits are accurate depends on the types of floating-point operations that have been performed. If it's just a few additions and subtractions, then all but the last digit are likely to be correct. But if you've been doing iterative numerical calculations, logarithms, exponentiation, trig functions ... then many digits will be inaccurate. In some cases, errors can accumulate to the point where the whole answer is useless, though this rarely happens outside the confines of serious mathematical computing.

For the above reasons, floating-point should not be used for fixed-point calculations, like currency calculations.

kenneth ga
Greenhorn
Posts: 9
Originally posted by Julian Kennedy:
Sorry Kenneth, I don't really see what you're getting at. If the value in a double named point_one is 0.1D then why would Double.toString(point_one) return 0.02 or 0.234?

hello jules, this is exactly my point that i want to be cleared out.
yes, indeed why should "0.1" be printed out as "0.02"?
but if it is printed as "0.10", is this a bug?

the specs of Double.toString(double), if i understood it correctly, does not specify on how many number of decimal places should be printed, so i can display "0.1000000000000000000000000000000" instead of just "0.1".

am i understanding it correctly?