GLBasic forum

Main forum => Bug Reports => Topic started by: Minion on 2012-May-03

Title: Float precision
Post by: Minion on 2012-May-03
Have a very weird bug here.

Code (glbasic) Select
LOCAL mx%=0
LOCAL manx=9.0
LOCAL c=0

REPEAT
manx=manx+0.2
mx=manx
PRINT mx+"   "+manx,0,c
c=c+16

UNTIL mx>15
SHOWSCREEN
KEYWAIT


and heres the results ...

Code (glbasic) Select
9   9.2
9   9.4
9   9.6
9   9.8
9   10
10   10.2
10   10.4
10   10.6
10   10.8
10   11
11   11.2
11   11.4
11   11.6
11   11.8
11   12
12   12.2
12   12.4
12   12.6
12   12.8
12   13
13   13.2
13   13.4
13   13.6
13   13.8
13   14
14   14.2
14   14.4
14   14.6
14   14.8
14   15
15   15.2
15   15.4
15   15.6
15   15.8
15   16
16   16.2


notice that when manx is a whole number and i assign it to the int, it doesnt register it as such ;(
Title: Re: Float precision
Post by: MrTAToad on 2012-May-03
Its more of a display oddity than floating precision.  For example, when it displays 10, it's actually 9.9999999999999999999993552713679

For best results, you should use FORMAT$ and take the integer value from that, thus :

Code (glbasic) Select
LOCAL mx%=0
LOCAL manx=9.0
LOCAL c=0
LOCAL temp$

REPEAT
manx=manx+0.2
temp$=FORMAT$(5,2,manx)
mx=INTEGER(temp$)
PRINT mx+"   "+temp$,0,c
c=c+16

UNTIL mx>15
SHOWSCREEN
KEYWAIT


[edit]
10.0 is internally 9.99999999999xxx not 9.00000000000xx ;)
Title: Re: Float precision
Post by: Minion on 2012-May-03
Thanks for the infor, but sadly thats not a viable option. Strings are very slow and using hundreds of them will slow down my program no end ;(

Title: Re: Float precision
Post by: Kitty Hello on 2012-May-03
If you work with floats, never ever rely on 1+1=2.
Always have an epsilon (tiny noise value) for comparisons:

IF ABS(a-b) < 0.000001 THEN

instead of
IF a = b THEN

Title: Re: Float precision
Post by: bigsofty on 2012-May-03
You could push it over the edge, dunno if that's a viable way to do it though...  :S

Code (glbasic) Select
mx=manx+0.000000000001

Edit: number was too small, so I changed it, doh!
Title: Re: Float precision
Post by: Slydog on 2012-May-03
What a pain this is, but not much we can do about it.

Well, you could try:
Code (glbasic) Select
LOCAL manx=9.000000000001 // or however many '0' are allowed

I hate how floats can round down below the integer version of its value.
Too bad we couldn't force them to always round up a bit  (or down if negative).
Ah, the nature of floats!
Title: Re: Float precision
Post by: Minion on 2012-May-03
Its a bit of a bugger. Im going to have to scrap floats from my interpreter now ;(
Title: Re: Float precision
Post by: fivesprites on 2012-May-03
or...

IMPORT "C" double round(double)

mx = round(manx)

manx = 9.2, mx = 9
manx = 9.4, mx = 9
manx = 9.6, mx = 10
manx = 9.8, mx = 10
manx = 10, mx = 10
manx = 10.2, mx = 10
manx = 10.4, mx = 10
manx = 10.6, mx = 11

Title: Re: Float precision
Post by: Slydog on 2012-May-03
You can always keep your 'floats' in integer form, if you want a certain precision.
If you only need one decimal place, multiply by 10, 2 decimals, multiply by 100, etc.

Then convert them when you need to display them (or in other calculations):

Code (glbasic) Select
LOCAL manx%=90  // Really 9.0 - This 'float' is stored as an integer x 10
LOCAL c=0

REPEAT
manx=manx+2  // Really + 0.2
PRINT INTEGER(manx/10)+"   "+manx/10,0,c
c=c+16
UNTIL manx>150
SHOWSCREEN
KEYWAIT
Title: Re: Float precision
Post by: spacefractal on 2012-May-03
Not a bug, it's depend what value was present in a binary form before calculated:

http://blogs.office.com/b/microsoft-excel/archive/2008/04/10/understanding-floating-point-precision-aka-why-does-excel-give-me-seemingly-wrong-answers.aspx

Hence would been nice as a round command directly from float to int (same as format does, but directly). Small thing.
Title: Re: Float precision
Post by: Minion on 2012-May-03
(mainly for gernot)...what routine are you using in order to display the float ? If I print a float it says 10.2, but if i compare it to 10.2 it does nothing. If i could use the same routine that is used when printing that would fix my problem.
Title: Re: Float precision
Post by: fivesprites on 2012-May-03
Or, if this is what you're after:

manx = 9, mx = 9
manx = 9.2, mx = 9
manx = 9.4, mx = 9
manx = 9.6, mx = 9
manx = 9.8, mx = 9
manx = 10, mx = 10
manx = 10.2, mx = 10
manx = 10.4, mx = 10
manx = 10.6, mx = 10

then you can get it with:

IMPORT "C" double ceil(double)

mx = ceil(manx*100)/100.0


Title: Re: Float precision
Post by: Moru on 2012-May-03
Or the classical:

Code (glbasic) Select
mx=manx+0.05

If I understand you correctly that you want mx to be the integer of manx? No need to import c functions for this.

Oh, and if you are just debugging numbers you can use the "DEBUG" command to just type it out in the debug-window so you don't have to bother with positioning text on the screen.

Code (glbasic) Select
DEBUG "\n mx="+mx+" manx="+manx
Title: Re: Float precision
Post by: Minion on 2012-May-03
Problem solved. Ive given myself 5 decimal places precision in my floats, and now there is no trouble comparing things like 10.2 (it didnt work before, id print the value and it would say 10.2, but if i did a compare it didnt accept it) all works fine now. Im happy.
Title: Re: Float precision
Post by: MrTAToad on 2012-May-04
Could always use fixed point maths :)