Java-Gaming.org
 Featured games (81) games approved by the League of Dukes Games in Showcase (498) Games in Android Showcase (117) games submitted by our members Games in WIP (563) 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 2073 times) 0 Members and 1 Guest are viewing this topic.
ryanm

Senior Member

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 Member

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 Member

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: 15
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 Member

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 Member

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 Member

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: 15
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 Member

 « 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 Member

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.
 Grunnt (13 views) 2014-09-23 14:38:19 radar3301 (14 views) 2014-09-21 23:33:17 BurntPizza (31 views) 2014-09-21 02:42:18 BurntPizza (22 views) 2014-09-21 01:30:30 moogie (20 views) 2014-09-21 00:26:15 UprightPath (29 views) 2014-09-20 20:14:06 BurntPizza (33 views) 2014-09-19 03:14:18 Dwinin (48 views) 2014-09-12 09:08:26 Norakomi (75 views) 2014-09-10 13:57:51 TehJavaDev (105 views) 2014-09-10 06:39:09
 BurntPizza 37x Rayvolution 23x Riven 19x princec 18x KevinWorkman 17x basil_ 16x KdotJPG 16x LiquidNitrogen 12x Mike 12x kevglass 12x deathpat 11x nsigma 11x ags1 10x theagentd 9x HeroesGraveDev 8x Gibbo3771 6x
 List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27Resources for WIP games2014-08-01 16:20:17Resources for WIP games2014-08-01 16:19:50List of Learning Resources2014-07-31 16:29:50List of Learning Resources2014-07-31 16:26:06List of Learning Resources2014-07-31 11:54:12HotSpot Optionsby dleskov2014-07-08 01:59:08
 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