Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / BIG SERIOUS MATH BUG OR WHAT?

Author
Message
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 13:40
Hello everybody,

I've discovered a serious issue that affects basic arithmetic operators (+, -, *, /) and therefore ANY program.

How can this be:

100 + 0.0001 = 100

This makes impossible a lot of calculations. For example I bet you cannot do an Euro conversion tool with this.

As the manual says, float is 7 digits and double float is 15 digits, but as soon as you operate with it, it seems it has 6 significant digits including decimal and non-decimal places.

This means that I cannot add a very small number to a very big one, because the big one will make the result always an integer!

There are lots of problems derived from this. As you know most calculations are made in a iterative-repetitive way, and this means that the error is cumulative too!

Look at my code example and run it.
It makes no difference to put Double Float, Float, or nothing!

Please call Lee Bamber and tell me how to deal with this!

If you think this does not matter I can provide you with lots of examples. In my current program, that 'integer cast' result makes impossible to do smooth movements for the objects that depends on these arithmetic operations, they just 'jump' from integer value to integer value!

Are we using a computer or what!?
Mentor
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 14:33 Edited at: 9th May 2003 15:12
OOPS! trust me to give the wrong answer in a busy post :-s , I originaly thought this was another newbie type "help I can`t do float math with integers" type post, than after I replied I noticed it wasn`t (DOH!) , you dont actualy need the type symbol (check the math example in the help) when you name the variable AS something or other, so you can leave the # sign out, and it isn`t a problem in the print statement cos the initial fractional value is displayed ok, it does seem to be a problem with the double precision numbers, I think the math is being done in single precision and DB is ignoreing the precision of the numbers it is working in, weird, we did have a problem with the displayed values but that got fixed, now it`s just the math that doesn`t work, lol.

Mentor.

Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 14:42 Edited at: 10th May 2003 17:19
try this

0.0001 + 100.0

its 100

(!!!)

try the code below I'm using double float and hash sign eveywhere!




What do you have to say?

We all asume these operations work well, but I have lost lots of hours for trusting this. They do not work properly. It's unnaceptable.
Flashing Blade
23
Years of Service
User Offline
Joined: 19th Oct 2002
Location: United Kingdom
Posted: 9th May 2003 14:44
that makes no difference in the problem he got.

He's defined test# as a DOUBLE FLOAT and (according to the manual & online help) DOUBLE FLOAT should be accurate upto and including 15 digits.

It's not - try his source code.
(In fact try your own suggestion - that prints 100 and not 100.0001)
Flashing Blade
23
Years of Service
User Offline
Joined: 19th Oct 2002
Location: United Kingdom
Posted: 9th May 2003 14:45
lol forget my post

i was answering Mentor - his post gone
Rob K
Retired Moderator
23
Years of Service
User Offline
Joined: 10th Sep 2002
Location: Surrey, United Kingdom
Posted: 9th May 2003 14:46
@Morcilla

Maybe the bug is in the PRINT function, not the maths.

Do you want Windows menus in your DBP apps? - Get my plugin: http://snow.prohosting.com/~clone99/downloads/tpc_menus_101.zip
Flashing Blade
23
Years of Service
User Offline
Joined: 19th Oct 2002
Location: United Kingdom
Posted: 9th May 2003 14:50
i think you right RobK

try this:

Cras
23
Years of Service
User Offline
Joined: 15th Oct 2002
Location: United Kingdom
Posted: 9th May 2003 14:52 Edited at: 9th May 2003 14:55
ignore me, this post is too active to make it worth me typing

p.s i did have something written here i just changed my mind.
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 14:53
Rob K, when I use the values for positioning objects, the object 'jumps' -it does not do a smooth movement-.

If I print those values I see the object jumping as the value suddenly changes (let's say 100, 101, 102, ... instead of 100.0001, 100.0002, 100.0003,...)

If you want I can write down an example, but it's a fact that the value is internally rounded.

I think this issue is going to affect all of us sooner or later.
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 15:01
Ok, then explain this:



if you use the supossed right invisible value 'test#' in another operation, its value is not correct.
YarSnez
23
Years of Service
User Offline
Joined: 9th Apr 2003
Location:
Posted: 9th May 2003 15:02
Yes, I think there is a problem with displaying floats with the print command. If you replace the print with the Text command the values are displayed correctly.
Flashing Blade
23
Years of Service
User Offline
Joined: 19th Oct 2002
Location: United Kingdom
Posted: 9th May 2003 15:09
if you use text instead of print you find out the math aint dead accurate
Mentor
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 15:13 Edited at: 9th May 2003 15:17
no..the math doesn`t work, just like you said, see my original post (the one I edited cos I gave the wrong answer :-s )

Mentor.

Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 15:28
Well I asume the print command does not work, but the result is still incorrect:

100 + 0.0001 = 100.0000991821289





now put it in a for...next 1000 times:




as you see the cumulative error can be serious.
Darkheart
23
Years of Service
User Offline
Joined: 2nd May 2003
Location:
Posted: 9th May 2003 15:28 Edited at: 9th May 2003 15:28
Whatever the manual says I think Darkbasic Pro only supports single floats for example I bet the snippet below works. So Darkbasic Pro only treats the values as single floats even if it says double. This isn't a huge problem as long as you don't need double prescision at least the basic maths is working. It's probably just another feature in DBP that doesn't work yet.

Click the source button below to see what I mean.

Darkheart

Richard Davey
Retired Moderator
24
Years of Service
User Offline
Joined: 30th Apr 2002
Location: On the Jupiter Probe
Posted: 9th May 2003 15:30
Sorry guys but there is nothing wrong with the maths calculations as you posted originally, the problem is the fact you're printing a direct variable that hasn't been converted to a String by the str$() function so is instead converted via the Print command which doesn't handle double floats.

Also you don't need the # when using a definition:

test AS DOUBLE FLOAT

will work just fine.

See the source attached to this message. It's your original post and I did nothing but use the str$() command to format the floats properly and it shows me the correct results each time.

There is however some issue with sequencing and rounding-up (or down) of values beyond a certain precision although I've asked Lee why it does this so will await his reply.

Cheers,

Rich

"Gentlemen, we are about to short-circuit the Universe!"
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 15:34
Thanks mentor, now we agree.
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 15:45 Edited at: 9th May 2003 15:56
DarkHeart!! I already noticed this,

10 + 0.0001 works fine, until 99 + 0.0001, but now try with a 3 or more digit number like 100.0, 300.0 or 1000.0 IT DOES NOT WORK!



Rich, thanks a lot, I knew there was a problem.
This rounding issue affect any program that has repetitive operations. Please look at my for...next example below:



Thats a 0,022092382813 deviation from the correct value. I don't want to think what could happen with bigger values.

And how it is explained that 8.309618*10^-2 = 0 ???
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 9th May 2003 15:54
This is mostly a misunderstanding of what the compiler is doing and how floating point numbers are implemented on the Intel platform.

100+0.5 = 100.5
Correct. An int with a fp, converts the int to fp, adds the number then returns a fp result.
Conversion only takes place as needed.

eg 100/1000*5.0 does this
integer 100 divided by integer 1000 = integer 0 (no decimal places allowed in integers)
integer 0 converted to float
float 0 multiply by float 0.5 = float 0.

100.0+0.1 = 100.09999847412109
Correct-ish. 0.1 is not directly representable in fp, so the nearest representable number to this is actually used. This is for the same reason that one-third is not representable in decimal, and we use approximations by rounding down at some point.

I've posted links from MSDN before on this subject.

DBPro only uses double floats for calculations. When you pass them as arguments to commands or functions, they are converted to single precision floats.

Also, this fixes your problem
8.309618*10.0^-2
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 16:04 Edited at: 9th May 2003 16:05
IanM,

I undestand the point of integer conversions, but I do not get that

"0.1 is not directly representable in fp"

I've been programming for years, and any C program can give you the correct results in an Intel platform, as the WINDOWS CALCULATOR does.

And,

"Also, this fixes your problem
8.309618*10.0^-2 "

I do not see how this fixes anything, please can you explain me?
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 9th May 2003 16:17 Edited at: 9th May 2003 16:18
Ok, first the explanation of the change I made to your equation.

10^-2 breaks down like this

integer 10 raised to the power of integer -2 = 0 (actual result would be 0.01 *if* we were using floating point)

And any number raised to the power of zero is zero.

Next, windows calculator does *not* use floating point representation. It uses another type of representation (probably BCD) to keep your numbers going from 'funny'.


I've had a look (again!) for that MSDN link - here it is. Please read the last few paragraphs (single precision are 4 byte reals, and double precision are 8 byte reals).

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_ieee_floating.2d.point_representation_and_microsoft_languages.asp
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 9th May 2003 16:21 Edited at: 9th May 2003 16:24
Oh, BTW, I'm *not* saying that the print and str$ commands/functions are doing what is expected, just that the maths is fine.

C does print the expected numbers, but that is because it is adjusting (rounding) to fit into the expected precision.

For example, one compiler I'm using on Intel (gcc 3.2) stores 0.1 as 0.1000000015 but displays 0.100000 with 'printf("%f",x);'
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 16:37 Edited at: 9th May 2003 16:48
IanM, mmm, I get what you say about 10^-2 =0.

It seems, for what it is said in the MSDN link that every Visual C++ program has the same issue.

I didn't expect this.

I've copied the example that cames in:
[href]
http://msdn.microsoft.com/library/en-us/vccore98/html/_core_why_floating_point_numbers_may_lose_precision.asp?frame=true[/href]

is this piece of code:


So I guess we'll have to get and use a Binary Coded Decimal (BCD) library that will maintain the precision.

Anyone knows where to find one?
zenassem
23
Years of Service
User Offline
Joined: 10th Mar 2003
Location: Long Island, NY
Posted: 9th May 2003 17:00
Actually any number raised to the power of 0 should equal 1. Mathematically speaking.

Mentor
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 17:15
Rich. the 3rd and 4th lines of Morcilla`s code

test#=0.000151625
print "0.000151625= ", test#

display the number correctly, so print does display 0.000151625 correctly when it converts test# (or test), yet in the other calculations it only gets to 5 decimal places, if it was the print conversion that had the problem surely it would display 0.000151625 as 0.00015 ?, it seems that as long as the double float is untouched the value is correct, but as soon as some calculation is done to it, it gets converted to single precision, thats what it looks like to me, at a guess the math system uses single precision and casts to single when asked to calculate a double, sorta loses the whole idea of having a double precision float I would have thought.

Mentor.

Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 17:54
This example below shows how a simple add and substract operations can cause problems in object behaviour:




This shows how a value can become to 'discrete', so the white cone jumps, and the other does not. PLEASE TRY!
haggisman
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 18:25
adding brackets to it makes it work fine



Specs:- 1GHZ athlon, Radeon8500, 192mb ram, winxp
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 18:43
Brackets shoudn't be neccesary as * is computed prior +, and that means a LOT of programs could be wrong!
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 18:50
I think DBPro does have a different order for operators...

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 9th May 2003 19:10
Well I've got another example, nearer to my program:



As you can test, the variable aux2 change as a real number without brackets!!!

But as soon as I add aux and aux2, the result is like 'discrete values'.

Tell me how can I bracket a = b + c ?

( how can I bracket in my example: real_value = aux + aux2 ?!!!)
haggisman
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 9th May 2003 19:26
its nothing to do with the maths, its just not being displayed to the full accuracy...



Specs:- 1GHZ athlon, Radeon8500, 192mb ram, winxp
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 9th May 2003 20:47
Zenassem: You are right, but read the code again. That is not what is being done here.

Morcilla: I can't defend DBPro's operator precedence, but I can offer a tip - bracket everything
Scorpyo
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: italy
Posted: 9th May 2003 23:55
UUrrrgghhhh....all this will wreck my hyper space jumps.......
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 10th May 2003 01:01
Not if you use brackets...

Repeat after me : Brackets are your best friends...

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
Kentaree
23
Years of Service
User Offline
Joined: 5th Oct 2002
Location: Clonmel, Ireland
Posted: 10th May 2003 01:21
Ok, "Brackets are your best friends...", hey, that wasnt so bad

Whatever I did I didn't do it!
EddieRay
23
Years of Service
User Offline
Joined: 28th Feb 2003
Location: USA
Posted: 10th May 2003 01:50
Minor note: This may be a language thing, but "brackets" is typically used to refer to "square brackets" (in computer terminology), and the ( and ) characters are gernerally referred to "parentheses". { and } are generally referred to as "curly braces".

So, the rule of thumb for expressions in DBPro would be: Parentheses are your friends.

IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 10th May 2003 03:00
They'll always be brackets to me
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 10th May 2003 03:32
I think you don't get the point, please tell me where do you want to put those parentheses in:

a = a + b

Please take a look at the code below,

10000.1 * 1000 = 10000100

10000.1 + 10000.1 one thousand times = 10000025
(75 units less!!!, if they were for example, 75 pounds, what would you tell me!!!)



There is a round factor that affects every arithmetical operation!
This is no good.
Richard Davey
Retired Moderator
24
Years of Service
User Offline
Joined: 30th Apr 2002
Location: On the Jupiter Probe
Posted: 10th May 2003 04:17
This rounding is quite standard though I'm afraid.

I had to change your code in order to get it to work in Blitz (you can see it in the Source code attached to this message) so that instead of 10000.1 * 1000 it was only 1000.1 * 1000.

Here are the results though:

DarkBASIC Professional:

1000.1 = 1000.099975585938
1000.1 * 1000 = 1000099.975585938
1000.1 * 1000 = 1000100

Blitz Basic:

1000.1 = 1000.099976
1000.1 * 1000 = 1000109.562500
1000.1 * 1000 = 1000100.000000

Neither are exactly "spot on" are they? Although if it was £ pounds we were dealing with, I'd rather have Blitz's results

All I'm trying to show is that this isn't just a DB thing.

Cheers,

Rich

"Gentlemen, we are about to short-circuit the Universe!"
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 10th May 2003 05:00 Edited at: 10th May 2003 05:02
Thanks for the feedback rich, perhaps you could try this too:



Here is the output:



Why do we have 13 decimal places for 100+100 and none at all for numbers greater than 1,000,000 ? Where are the 15 digits?

other strange results:

1,000,000 + 100 (0.1 1000 times) = 1,000,125
10,000,000 + 100 (0.1 1000 times) = 10,000,000
100,000,000 + 100 (0.1 1000 times) = 100,000,000


I need to work with big numbers with some decimals (the more, the better)
Once again, How can I cast the 15 digits?
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 10th May 2003 14:09 Edited at: 10th May 2003 14:35
I MUST INSIST:

HOW CAN IT BE


10000000.0 + 0.1 = 10000000.0

!!!?



a as double float
b as double float
c as double float

a = 10000000.0

b = 0.1

c = a + b


print "a = " , str$(a)
print "b = " , str$(b)
print "c = a + b = ", str$(c)

sync
suspend for key





Where is the double float precision of 15 digits?
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 10th May 2003 15:08 Edited at: 10th May 2003 15:13
In this case, I think there is a problem with str$...

Mind you, it does say it can only handle integers...

Possibly a case for a plug-in...

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
David T
Retired Moderator
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: England
Posted: 10th May 2003 16:57
My largest problem is:

percent# = (health / max)*100

eg.

percent# = (50 / 100)*100

giving percent# then value of "0". I managed to get it to work by putting this once:

percent# = ((health * 1.0) / (max * 1.0))*100.0

but that is too complex to be of any use!

You are the th person to view this signature.
Programmers don't die, they just Gosub without return....
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 10th May 2003 17:10 Edited at: 10th May 2003 17:11
MrTAToad, Rich tell us above to use the str$() function.

I'm still thinking that there is a digit limitation when operating, that implies both operands, and that the values get rounded in an undesirable way.

If at least we could discard some decimal places with a round function, and even so, we would have to do our operations carefully.
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 10th May 2003 20:33
I do think there is a problem with str$ in this respect....

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
Morcilla
23
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 10th May 2003 20:53
no problem MrTAToad, I wish it were (or I wish it is) !
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 11th May 2003 22:55
I think there is - I've got a plug-in that will display a double to 15dp now...

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 12th May 2003 01:35
Then you did too much

It's 15 digits of precision - an entirely different thing.
MrTAToad
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: United Kingdom
Posted: 12th May 2003 01:41
At least it shows Morcilla answer properly now...

Good news everyone! I really am THAT good...
http://www.nickk.nildram.co.uk/ for great plug-ins - oh my, yes!
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 12th May 2003 01:43


A satified customer? Well, we can but hope...

Login to post a reply

Server time is: 2026-07-11 12:18:32
Your offset time is: 2026-07-11 12:18:32