Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (604) Games in Android Showcase (171) games submitted by our members Games in WIP (653) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Floating point error  (Read 2429 times) 0 Members and 1 Guest are viewing this topic.
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.10.20.30.40.50.60.700000050.80000010.90000011.0000001`

Where does this error come from? Is it really too much to ask that simple addition works?
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
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`

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!
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

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
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?

GameLizard.com
Play Rimscape!    |    Play Conquer!
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 ).

shmoove
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++

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

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!
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
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

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
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.

 SHC (25 views) 2015-08-01 03:58:20 Jesse (19 views) 2015-07-29 04:35:27 Riven (40 views) 2015-07-27 16:38:00 Riven (21 views) 2015-07-27 15:35:20 Riven (24 views) 2015-07-27 12:26:13 Riven (14 views) 2015-07-27 12:23:39 BurntPizza (36 views) 2015-07-25 00:14:37 BurntPizza (46 views) 2015-07-24 22:06:39 BurntPizza (30 views) 2015-07-24 06:06:53 NoxInc (36 views) 2015-07-22 22:16:53
 theagentd 51x wessles 48x basil_ 35x KaiHH 26x orangepascal 26x ags1 21x Riven 19x mooman219 17x bornander 14x KudoDEV 13x CelestialCreator 11x princec 11x Jesse 11x klaus 10x pquiring 9x chrislo27 8x
 List of Learning Resourcesby gouessej2015-07-09 11:29:36How Do I Expand My Game?by bashfrog2015-06-14 11:34:43List of Learning Resources2015-05-31 05:37:30Intersection Methodsby Roquen2015-05-29 08:19:33List of Learning Resources2015-05-05 10:20:32How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21
 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