0
\$\begingroup\$

Hey all I have just come to notice that floats are not accurate even when they are explicitly set and unchanged. For example i have some basic code running and it is:

 if (bike.getY() < previousBikeY){
        bike.accelY = 50f;

        System.out.println("bike accel Y :" + bike.accelY);
    }

The result in the log is:

I/System.out: accelY: 49.770126

If I wanted 49.77 id have set 49.77, this also makes me wonder about all the other uses of float i have (such as position, speed, gravity, time, etc).

A) Does this happen in other languages such as C++ or C#? B) is this normal and something i should ignore OR do I need to take action?

\$\endgroup\$
  • 2
    \$\begingroup\$ floating-point-gui.de \$\endgroup\$ – Vaillancourt Mar 6 '17 at 19:26
  • \$\begingroup\$ thanks that has helped clarify. however it doesn't actually explain why 50f is 49.77777 because it refers to the computer not being able to represent fractions of a number correctly, but 50 is a whole number so i still dont really understand why it can't \$\endgroup\$ – Big T Larrity Mar 6 '17 at 19:30
  • 1
    \$\begingroup\$ Is your machine a binary machine? If yes, there's no reason why 50 should be converted to something else without other side effects. \$\endgroup\$ – GameDeveloper Mar 6 '17 at 19:31
  • 2
    \$\begingroup\$ "but 50 is a whole number," Well, floats cannot represent all integers accurately. However, 50.0 can be represented exactly. What's more likely is that the transformation is occurring as a result of the string formatting. \$\endgroup\$ – Josh Mar 6 '17 at 19:34
  • 1
    \$\begingroup\$ Since there's a syntax error in your example code (missing a closing paren), it suggests you retyped this from memory instead of copying and pasting directly. In doing so you may have omitted relevant information. \$\endgroup\$ – Josh Mar 6 '17 at 19:36
1
\$\begingroup\$

IMO this is a general programming question and is therefore out of place here. However;

A.) Yes, this happens in all programming languages to varying degrees (well, at least the ones I have worked with, those being Java, and C# (not sure about lua or javascript)).

B.) This is very normal and the reason is discussed here. Whether you should take special considerations depends on what you are doing and the degree of accuracy you need to maintain. If you are getting floating point precision issues in comparisons (that is, (50f == 49.770126) == false) you can do the following:

float eps = 0.000001;
if((val - comparedTo) < eps)
    System.out.println("We have a match!");

Where eps is the decimal precision you need you comparison to check.

\$\endgroup\$
  • \$\begingroup\$ Technically speaking, does not happen in all languages, some "exotic" scripting languages work with fractional and string representations of real numbers rather than floating point ones (assuming the question was actually about real numbers). \$\endgroup\$ – wondra Mar 7 '17 at 8:46
  • \$\begingroup\$ @wondra Which is why I included this in my answer "Well, at least the ones I have worked with, those being Java, and C#" :-) \$\endgroup\$ – JDSweetBeat Mar 7 '17 at 14:06
  • 1
    \$\begingroup\$ No need to be so defensive, as matter of fact there is also SqlDecimal in C# in System.Data namespace which is a "numeric value between - 10^38 +1 and 10^38 - 1, with fixed precision and scale" thus precise. But is another of those exotic solutions. \$\endgroup\$ – wondra Mar 7 '17 at 14:29
  • \$\begingroup\$ @wondra Not trying to sound defensive, I was just pointing that I mentioned that out. And that is very interesting, I honestly didn't know that and I have been working with C# for over a year. ;-) \$\endgroup\$ – JDSweetBeat Mar 7 '17 at 15:05
1
\$\begingroup\$

To answer strictly to your question, no it does not happens on other languages.

While it is true that floating point cannot represent all numbers, small whole numbers should be represented correctly. Infact if you try the following floating point converter with "50.0f" value, you will se "50".

https://www.h-schmidt.net/FloatConverter/IEEE754.html

To me it looks like that variable was not simply assigned, but underwent some additional processing (likely to be some transformation matrix or something similiar).

The quickest way to check that is to do some extra tests (also to remove the chance the bug is actually only in the visualization of the debug log).

try the following

bike.accelY = 50f;
if((bike.accelY +1f)  == 51f)
     System.out.println("Value was 50 and just displayed wrongly");
else
     System.out.println("Value went under further processing");

If the value is processed I would be surprised, because Java (as far as I know) does not have properties (like C#, or do they added properties?)

\$\endgroup\$
  • \$\begingroup\$ Hi, thanks for the reply. I added your code and the log states "went under further processing" but i can assure you it doesn't . The reason that line is printed is just because bike.accelY + 1f isn't exactly 51, which leads me back to my original question. I'm kinda hoping i can 'ignore' it since I only just noticed , but not sure and im having some issues with my code (related to bools, not being called true) but i dont think the float accuracy really is the problem in my case here \$\endgroup\$ – Big T Larrity Mar 6 '17 at 19:38
  • \$\begingroup\$ yes AFAIK it's a binary machine. Aren't all PCs?? i dunno! Well its a intel i7 4790k with with windows 10 so hopefully that would confirm it \$\endgroup\$ – Big T Larrity Mar 6 '17 at 19:52
  • \$\begingroup\$ Yes, the binary machine was sarchastic, because libGDX should have done something really wrong to get your "50" changed into something else. I suspected it was some hidden effect. Do you have threaded code? it could also be a race condition. (I could understand if that code was C#, since a simple member assignment could hide more complex operations.. but this is Java! so IDK). \$\endgroup\$ – GameDeveloper Mar 6 '17 at 19:56
  • 1
    \$\begingroup\$ well its strange (and sorry for delayed reply was watching footy haha) I just set the vlue to 50f, then instantly call the println. Ill try looking harder in a minute as it must be something in my bike class I guess \$\endgroup\$ – Big T Larrity Mar 6 '17 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.