kenneth ga

Greenhorn

Posts: 9

posted 13 years ago

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.

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

posted 13 years ago

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.

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.

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.

kenneth ga

Greenhorn

Posts: 9

posted 13 years ago

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?

I really appreciate your help.

thanks.

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?

I really appreciate your help.

thanks.

Julian Kennedy

Ranch Hand

Posts: 823

posted 13 years ago

I recently posted this in another thread:

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

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

posted 13 years ago

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.

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

posted 13 years ago

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

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

posted 13 years ago

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.

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.

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.

kenneth ga

Greenhorn

Posts: 9

posted 13 years ago

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?

thanks in advance.

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?

thanks in advance.