• Post Reply Bookmark Topic Watch Topic
  • New Topic

Value changed after casting from float to double?  RSS feed

 
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

Maybe this is a very old topic and has been discussed thousands of times before, but now it gives me a big headache.

In my current project, I need to receive data from a legacy program. What I expected is a double value, i.e. 3.14, and what is given to me is a float value, i.e. 3.14.
When the float value casts to a double value, to my surprise, the resulted value changed and some no-zero decimals are generated in the cast result!

In order to investigate this issue, I did a quick test and the result is very interesting.

Here is my sample code

float testFloat = (float) 3.14;
double testDouble = 3.14;
double testDouble2 = (float)3.14;
System.out.println("testFloat:" +testFloat);
System.out.println("testDouble:" +testDouble);
System.out.println("testDouble2:" +testDouble2);

Here is the result
testFloat:3.14
testDouble:3.14
testDouble2:3.140000104904175

Clearly after casting, float 3.14 changed to 3.140000104904175

Why float 3.14 does not stay as double 3.140000000000000 and how to solve it?

BTW, I an using Oracle JDeveloper 10g, results are the same whether it is running in hotpot JVM or oracle OJVM

Thanks

Howard
 
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not an advanced topic.

The float and double types are floating-point. All such types have limited precision and cannot represent all numbers accurately. Because they are binary, not decimal, some numbers that look "simple" (e.g. 3.14) in decimal still cannot be represented exactly by floating-point.

So questions about the exact value of float and double variables are not very interesting at all. Inaccuracy is a feature of these types, and you either have to live with it, or choose a different type.
 
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Howard"

Welcome to JavaRanch!

Please can you update your display name so it complies with our Naming Policy. You can do this here.

Thanks.
 
Paul Sturrock
Bartender
Posts: 10336
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
... and as Peter Chase points out, this isn't really an advanced topic. I'll move this to a more suitable forum.
 
Howard Zhao
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

Thank you very much for your prompt response!

I very agree with you on that the inaccuracy is introduced by the floating-point number binary representation.

Besides the Java test, we also did a c++ test on Windows.

double d = (float) 3.14;
printf(�%0.20lf�, d);

The result is 3.14000000000000010000.

Why Java is not as accurate as C++? Is it because of different Java compiler implementation? Or because of different JVM implementation?

Thanks again

Howard
 
Marshal
Posts: 56610
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Posted by Howard Zhao
Why Java is not as accurate as C++?
It's not a case of accuracy; both figures are as accurate as each other.
It's a case of precision.

I am not sure about C++, but in C and C#, float values are expressed as 32-bit IEEE 754 (as here in the JLS) format. The float type has approx 6 or 7 significant figures' precision, unless you go into small fractions where |x| < 1/Float.MAX_VALUE (2.938736 e -39). The Java example you quote seems to give about 7 significant figures.
You are familiar with the concept of extension of floating-point numbers? The JVM can use increased bits for intermediate operations in arithmetic, unless you are using strictfp arithmetic, which sacrifices precision for reproducibility, so the calculations give exactly the same result on any computer. Here the JLS tells us about strictfp. It might be that the C++ compiler you are using can extend the limits of the number for enhanced precision.

As you say, this will vary from compiler to compiler and VM to VM, but when
I tried your casts, in C with 20 places after the decimal point, I got,
  • testFloat = 3.14000010490417480000
  • testDouble = 3.13999999999999968000, and,
  • testDouble2 = 3.13999999999999968000 Press any key to continue ...
  • and copying and pasting your Java code:
  • A:\>java FloatCast
  • testFloat:3.14
  • testDouble:3.14
  • testDouble2:3.140000104904175
  • That is as far as I can get with it, but the lesson is that floating-point arithmetic always has some imprecision to it.
    CR
     
    Campbell Ritchie
    Marshal
    Posts: 56610
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I tried the same sort of thing in C# and got:-
    testFloat = 3.14, testDouble = 3.14, testDouble2 = 3.14000010490417
    CR
     
    Howard Zhao
    Greenhorn
    Posts: 27
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi
    Thank all of you very much for the replies.
    I have decided to change all the float-type variables to double-type.

    Thanks again.

    Howard
     
    Greenhorn
    Posts: 10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    -----------------------------------------------
    Originally posted by Howard Zhao

    float testFloat = (float) 3.14;
    double testDouble = 3.14;
    double testDouble2 = (float)3.14; //(1)
    ----------------------------------------------
    I changed the line (1) to
    double testDouble2 = (double)3.14;

    the result is :

    testFloat:3.14
    testDouble:3.14
    testDouble2:3.14

    Cheers,
    Parshuram.
     
    Ranch Hand
    Posts: 802
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    my prof said that floating point values are "bad" and that no one really

    uses them anymore... i cant really remember why he said that, but this

    example of conversion gives me an idea....

    is this opinion of "floats are bad and out" wrong?

    Justin
     
    author and iconoclast
    Sheriff
    Posts: 24217
    38
    Chrome Eclipse IDE Mac OS X
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Justin Fox:

    is this opinion of "floats are bad and out" wrong?


    Either you misinterpreted what s/he said, or... not, sadly. Maybe s/he was telling you that using floating-point to represent finite decimals like monetary amounts is bad -- and that much is correct.

    But in either case, no, floating point number aren't bad, not at all. What's bad is assuming that they're exact.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!