Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (541)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Floating point error  (Read 2179 times)
0 Members and 1 Guest are viewing this topic.
Offline ryanm

Senior Devvie


Projects: 1
Exp: 15 years


Used to be bleb


« Posted 2005-05-10 07:56:03 »

This is something that's annoyed me for ages:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class FPError
{
    public static void main( String[] args )
    {
        float f = 0.0f;
        for( int i = 0; i < 10; i++ )
        {
            f += 0.1f;
            System.out.println( f );
        }
    }
}

gives
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001
1.0000001


Where does this error come from? Is it really too much to ask that simple addition works?
Offline shmoove

Junior Devvie




Doh!


« Reply #1 - Posted 2005-05-10 08:11:52 »

It comes from the fact that numbers are stored in binary in a finite sequence of bytes. If you could only remember numbers in decimal notation with a predetermined amount of digits, you would see the same problem when you try to do things with amounts like 1/3:

1  
2  
3  
4  
5  
// using 4 digits:
1/3 = 0.333 (not bad)
1/3 + 1/3 = 0.666 (still OK)
1/3 + 1/3 + 1/3 = 0.999 (looks fine for now)
1/3 + 1/3 + 1/3 + 1/3 = 1.332 (hey, wait a minute! shouldn't it be 1.333?)


shmoove
Offline ryanm

Senior Devvie


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #2 - Posted 2005-05-10 08:25:54 »

That sounds reasonable for fractions like 1/3, as you can't express that exactly no matter how many bytes are used.

But why for 0.6 and 0.1? AFAICS, there's no problem expressing them exactly in a 32-bit float.

Here's an even more concise test case:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public class FPError
{
    public static void main( String[] args )
    {
        float f = 0.1f + 0.6f;
        if( f != 0.7f )
        {
            System.out.println( "wtf? " + f );
        }
    }
}

gives:
1  
wtf? 0.70000005
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Markus_Persson

JGO Wizard


Medals: 16
Projects: 19


Mojang Specifications


« Reply #3 - Posted 2005-05-10 08:44:16 »

It has to do with what base you use for your numbers.
In base 3, 1/3 is expressed as exactly 0.1. No fractions.

In base 2 (binary), it becomes very tricky to exactly express 1/10. It's something like 0.0001100110...
I haven't worked out if it's infinitly long like 1/3 is in decimal (base 10), but I've got a feeling it just might be.

Play Minecraft!
Offline ryanm

Senior Devvie


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #4 - Posted 2005-05-10 09:13:59 »

You've got a point there.
Quote
AFAICS, there's no problem expressing them exactly in a 32-bit float.
Apparently, AFAICS isn't terribly far Roll Eyes

It appears there's nothing to be done except weep for the fact that a number commonly occuring in our decimal-based world is a pathological case for floating-point representation  Embarrassed
Offline Malohkan

Senior Devvie




while (true) System.out.println("WOO!!!!");


« Reply #5 - Posted 2005-05-10 12:10:12 »

if you do have a big problem with it, you can use classes like BigFloat and such, right?

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline shmoove

Junior Devvie




Doh!


« Reply #6 - Posted 2005-05-10 12:41:32 »

Or make your own RationalNumber class (unless you need irrational numbers, then you're screwed Smiley).

shmoove
Offline Jeff

JGO Coder




Got any cats?


« Reply #7 - Posted 2005-05-10 18:46:49 »

Yo uwant to have even more floating point fun?

How many starts does this method print?

1  
2  
3  
4  
5  
6  
7  
public method printStars(float start){
    float end  = start + 100;

    while (start++<end) {
        System.out.print("*");
    }
}

The answer is its indeterminate and based on the value of start.
Because floats are an aproximation whose accuracy changes with
the value, if start is high enough start++ becomes a nop lost iin
the rounding and its an idiot loop!

For this reason i personally believe that allowing ++ on floats was a syntactic error on the part of the original Java designers.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Markus_Persson

JGO Wizard


Medals: 16
Projects: 19


Mojang Specifications


« Reply #8 - Posted 2005-05-11 06:57:53 »

If so, +=1 shouldn't be allowed on floats either, since it'll fail for very large floats.

I guess it boils down to if you read i++ as "next" or as "+=1"

Play Minecraft!
Offline digitprop

Junior Devvie





« Reply #9 - Posted 2005-05-11 08:17:43 »

This is probably just a problem of internal representation vs. output / formatting. Just keep in mind that the internal representation is much more precise than you need your output to be (in most cases, that is; if not, then using float/double primitives is a bad idea anyway).

For example, this works nicely:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public static void main(String[] args)
{
      NumberFormat nf=new DecimalFormat("0.00");
     
      float f = 0.0f;
      for (int i = 0; i < 10; i++)
      {
            f += 0.1f;
            System.out.println(nf.format(f));
      }
}

M. Fischer . www.digitprop.com
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jeff

JGO Coder




Got any cats?


« Reply #10 - Posted 2005-05-11 19:36:27 »

Quote
If so, +=1 shouldn't be allowed on floats either, since it'll fail for very large floats.

I guess it boils down to if you read i++ as "next" or as "+=1"


Yup good point.

To me though +1 is ana rtihmatic operation while ++ is an ordinal increment.

Maybe im just weird Smiley

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline nonnus29

Senior Devvie




Giving Java a second chance after ludumdare fiasco


« Reply #11 - Posted 2005-05-11 21:43:48 »

Quote
Where does this error come from? Is it really too much to ask that simple addition works?


You're laboring under some misapprehensions here;

1.  It's not an error
2.  It does work

This is how floating point numbers are defined to work.

The alternatives are fixed point and binary coded decimal.  Floating point is used more than these today because of faster implimitations in hardware and better general purpose flexibility.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Mr.CodeIt (24 views)
2014-12-23 03:34:11

rwatson462 (55 views)
2014-12-15 09:26:44

Mr.CodeIt (45 views)
2014-12-14 19:50:38

BurntPizza (91 views)
2014-12-09 22:41:13

BurntPizza (113 views)
2014-12-08 04:46:31

JscottyBieshaar (83 views)
2014-12-05 12:39:02

SHC (92 views)
2014-12-03 16:27:13

CopyableCougar4 (100 views)
2014-11-29 21:32:03

toopeicgaming1999 (160 views)
2014-11-26 15:22:04

toopeicgaming1999 (163 views)
2014-11-26 15:20:36
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!