Claudiu
Claudiu

Reputation: 229521

Can 12.1 be represented exactly as a floating point number?

This is in reference to the comments in this question:

This code in Java produces 12.100000000000001 and this is using 64-bit doubles which can present 12.1 exactly. – Pyrolistical

Is this true? I felt that since a floating point number is represented as a sum of powers of two, you cannot represent 12.1 exactly, no matter how many bits you have. However, when I implemented both the algorithms and printed the results of calling them with (12.1, 3) with many significant digits, I get, for his and mine respectively:

12.10000000000000000000000000000000000000000000000000000000000000000000000000 12.10000000000000100000000000000000000000000000000000000000000000000000000000

I printed this using String.format("%76f"). I know that's more zeros than necessary, but I don't see any rounding in the 12.1 .

Upvotes: 4

Views: 3199

Answers (9)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 62002

No, the decimal number 12.1 cannot be represented as a finite (terminating) binary floating-point number.

Remember that 12.1 is the rational number 121/10. Note that this fraction is in lowest terms (cannot be reduced by removing common fators of the numerator an denominator).

Suppose (in order to reach a contradiction) that 121/10 could be written also as n / (2**k) where n and k are some positive integers, and 2**k denotes the kth power of two. We would have a counter-example to unique factorization. In particular

10 * n == 2**k * 121

where the left-hand side is divisible by 5 which the right-hand side is not.

Upvotes: 2

Alice
Alice

Reputation: 3986

Yes, you can exactly represent 12.1 in floating point. You merely need a decimal floating point representation, not a binary one.

Use the BigDecimal type, and you'll represent it exactly!

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533750

A way to see what the double is fairly exactly is to convert it to BigDecimal.

// prints 12.0999999999999996447286321199499070644378662109375
System.out.println(new BigDecimal(12.1));

Upvotes: 2

Rich Schuler
Rich Schuler

Reputation: 41972

I suggest reading What Every Computer Scientist Should Know About Floating Point Arithmetic. Then you'll know for sure. :)

Upvotes: 2

Michael Anderson
Michael Anderson

Reputation: 73570

One option that you can use is to not store v=0.1, but instead store v10=1. Just divide by 10 when needed ( the division will create truncation error in your result but v will still be OK )

In this case you're basically doing a fixed point hack, but keeping the number in a float. But its usually not worth doing this unless you really have to.

Upvotes: 0

Edmund
Edmund

Reputation: 10829

Not in binary, no. If you'll allow me to be fanciful, you could in "floating point binary coded decimal" (which, to the best of my knowledge, has never been implemented):

12.1 = 0000 . 0001 0010 0001 * (10^2)

In binary all non-zero values are of the form 1.xyz * m, and IEEE form takes advantage of this to omit the leading 1. I'm not sure what the equivalent is for FP-BCD, so I've gone for values of the form 0.xyz * m instead.

Upvotes: 3

wallyk
wallyk

Reputation: 57784

Try to express 0.1 in binary:
0.5 is too big
0.25 is too big
0.125 is too big
0.0625 fits, and leaves a remainder of 0.0375
0.03125 fits, and leaves a remainder of 0.00625
0.015625 is too big
0.0078125 is too big
0.00390625 fits, and leaves a remainder of 0.00234375
0.001953125 fits, and leaves a remainder of 0.000390625

It's going to keep repeating indefinitely, creating a base 2 value of 0.00011001100...

No, it can't be expressed exactly in a double. If Java supports BCD, or fixed point decimal, that would work exactly.

Upvotes: 9

Stephen Canon
Stephen Canon

Reputation: 106277

In binary, 12.1 is:

1100.000110011001100110011...

Since this doesn't terminate, it can't be represented exactly in the 53 significand bits of a double, or any other finite-width binary floating-point type.

Upvotes: 13

Aric TenEyck
Aric TenEyck

Reputation: 8032

No. As others noted in followups to his comment, no sum of (a finite number of) powers of two can ever add up to exactly 12.1. Just like you can't represent 1/3 exactly in base ten, no matter how many digits you use after the decimal point.

Upvotes: 15

Related Questions