0

I am trying to convert double to float in java.

Double d = 1234567.1234;
Float f = d.floatValue();

I see that the value of f is

1234567.1

I am not trying to print a string value of float. I just wonder what is the maximum number of digits not to lose any precision when converting double to float. Can i show more than 8 significant digits in java?

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
yrazlik
  • 10,411
  • 33
  • 99
  • 165
  • possible duplicate of [Double decimal formatting in Java](http://stackoverflow.com/questions/12806278/double-decimal-formatting-in-java) – Tunaki Aug 27 '15 at 19:05
  • @Tunaki i am not trying to print a string, i saw that the value of float while debugging. Edited the question. – yrazlik Aug 27 '15 at 19:09
  • What do you mean by "the maximum number of digits not to lose any precision"? The actual value of the Float value in your question is 1234567.125. – RealSkeptic Aug 27 '15 at 19:19
  • @RealSkeptic i just want to get the same value of double when converted to float. I mean what is the maximum number of digits for that? – yrazlik Aug 27 '15 at 19:21
  • 1
    Not all double values can be represented exactly as float values. That's actually the entire reason that double exists: to provide more precision (that is, more available numbers) than float. Moreover, "number of [decimal] digits" is an oversimplified (and thus doomed-to-fail) way to think about floating point numbers. – yshavit Aug 27 '15 at 19:31
  • The precision of `float` is in binary, so there is no single answer. In decimal, it's usually 7 digits. Although @RealSkeptic is right that the full value is `1234567.125`, that's actually too much for the effective precision, since the previous and next increments are `1234567.000` and `1234567.250`, so effective precision is about 1 decimal place for that number. – Andreas Aug 27 '15 at 19:33

5 Answers5

4

float: 32 bits (4 bytes) where 23 bits are used for the mantissa (6 to 9 decimal digits, about 7 on average). 8 bits are used for the exponent, so a float can “move” the decimal point to the right or to the left using those 8 bits. Doing so avoids storing lots of zeros in the mantissa as in 0.0000003 (3 × 10-7) or 3000000 (3 × 107). There is 1 bit used as the sign bit.

double: 64 bits (8 bytes) where 52 bits are used for the mantissa (15 to 17 decimal digits, about 16 on average). 11 bits are used for the exponent and 1 bit is the sign bit.

I believe you hit this limit what cause that problem.

If you change

Double d = 123456789.1234;
Float f = d.floatValue();

You will see that float value will be 1.23456792E8

StackFlowed
  • 6,664
  • 1
  • 29
  • 45
3

The precision of a float is about 7 decimals, but since floats are stored in binary, that's an approximation.

To illustrate the actual precision of the float value in question, try this:

double d = 1234567.1234;
float f = (float)d;
System.out.printf("%.9f%n", d);
System.out.printf("%.9f%n", Math.nextDown(f));
System.out.printf("%.9f%n", f);
System.out.printf("%.9f%n", Math.nextUp(f));

Output

1234567.123400000
1234567.000000000
1234567.125000000
1234567.250000000

As you can see, the effective decimal precision is about 1 decimal place for this number, or 8 digits, but if you ran the code with the number 9876543.9876, you get:

9876543.987600000
9876543.000000000
9876544.000000000
9876545.000000000

That's only 7 digits of precision.

Andreas
  • 154,647
  • 11
  • 152
  • 247
2

I just wonder what is the maximum number of digits not to lose any precision when converting double to float.

Maybe you don't realize it, but the concept of N digits precisions is already ambigous. Doubtlessly you meant "N digits precision in base 10". But unlike humans, our computers work with Base 2.

Its not possible to convert every number from Base X to Base Y (with a limited amount of retained digits) without loss of precision, e.g. the value of 1/3rd is perfectly accurately representable in Base 3 as "0.1". In Base 10 it has an infinite number of digits 0.3333333333333... Likewise, commonly perfectly representable numbers in Base 10, e.g. 0.1 need an infinite number of digits to be represented in Base 2. On the other hand, 0.5 (Base 10) is peferectly accurately representable as 0.1 (Base 2).

So back to

I just wonder what is the maximum number of digits not to lose any precision when converting double to float.

The answer is "it depends on the value". The commonly cited rule of thumb "float has about 6 to 7 digits decimal precision" is just an approximation. It can be much more or much less depending on the value.

When dealing with floating point the concept of relative accuracy is more useful, stop thinking about "digits" and replace it with relative error. Any number N (in range) is representable with an error of (at most) N / accuracy, and the accuracy is the number of mantissa bits in the chosen format (e.g. 23 (+1) for float, 52 (+1) for double). So a decimal number represented as a float is has a maximum approximation error of N / pow(2, 24). The error may be less, even zero, but it is never greater.

The 23+1 comes from the convention that floating point numbers are organized with the exponent chosen such that the first mantissa bit is always a 1 (whenever possible), so it doesn't need to be explicitly stored. The number of physically stored bits, e.g. 23 thus allows for one extra bit of accuracy. (There is an exceptional case where "whenever possible" does not apply, but lets ignore that here).

TL;DR: There is no fixed number of decimal digits accuracy in float or double.

Durandal
  • 19,919
  • 4
  • 36
  • 70
2

This is a simple example in support of the view that there is no safe number of decimal digits.

Consider 0.1.

The closest IEEE 754 64-bit binary floating point number has exact value 0.1000000000000000055511151231257827021181583404541015625. It converts to 32-bit binary floating point as 0.100000001490116119384765625, which is considerably further from 0.1.

There can be loss of precision with even a single significant digit and single decimal place.

Unless you really need the compactness of float, and have very relaxed precision requirements, it is generally better to just stick with double.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
1

EDIT.
No you cannot get any more precise with a float in Java because floats can only contain 32 bits ( 4 bytes). If you want more precision, then continue to use the Double. This might also be helpful

Community
  • 1
  • 1
Turtle
  • 1,369
  • 1
  • 17
  • 32