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 / Math Anomaly in DB Pro Online (big implications)

Author
Message
Minervo
11
Years of Service
User Offline
Joined: 30th Dec 2014
Location: United States
Posted: 3rd Jan 2015 06:06
I am just getting on board with DB Pro Online. I purchased the two books, and I am going through them and trying out code so that I can see how DB Pro reacts. Over the past 35 years or so, I have programmed in several languages, but I have never seen anything like this:

If you perform this math in your head, 12-5*12/10-5, the answer should be 1, right?

Wrong. DB Pro Online says the answer is 2

If you want the answer to be 1, then you have to use parens like this:
12-(5*12)/10-5

This is the oddest thing I have ever seen in any language. It is a simple thing but has huge implications when your code is doing math. If the programmer doesn't know about this anomaly and how to work around it, the code will be off and the error would never be found.

I am on page 84 of volume 1, and I wonder what other odd things I will find.

Minervo
pcRaider
19
Years of Service
User Offline
Joined: 30th May 2007
Location:
Posted: 3rd Jan 2015 10:26
print 12-5*12/10.0-5
wait key

the answer is 1

windowsXp
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 3rd Jan 2015 11:44 Edited at: 3rd Jan 2015 11:45
That is to be expected I think, the division is carried out before the multiplication and since you're using integers the result of the division will be a truncated integer (1), which means your equation will read as 12 - 5 - 5 = 12 - 10 = 2.

Technically speaking, and assuming I recall correctly, multiplication and division have the same operator priority which means that either one can be performed before the other; the same holds true for addition and subtraction but swapping those around won't affect the result; as such you should use paranthesises to specify which operation should be carried out first.

Of course, the answer will be 1 if you use floating point (fractional) values like pcRaider suggests as well, maybe that was what you were getting at?

Minervo
11
Years of Service
User Offline
Joined: 30th Dec 2014
Location: United States
Posted: 3rd Jan 2015 12:44
Thank you for your reply. Yes, I see. 10, an integer, might be stored by DB as 9.87988 or something. The book mentions this. I had tried to store the result of the equation in a real variable, but the answer was still 2. Therefore, DB truncated 9.8798 (or whatever) to 9 resulting in 2. It appears that the only reliable method of performing math is conversion of numbers to REAL before calculation, which pcRaider demonstrated. (I needed a universal rule to keep in mind.) I will play with this some more. I wonder if I have to use trickery like conversion to string then real. It is one thing with constants, but unknowns is, well, unknown.

Minervo
Le Verdier
14
Years of Service
User Offline
Joined: 10th Jan 2012
Location: In the mosh-pit
Posted: 3rd Jan 2015 17:03 Edited at: 3rd Jan 2015 17:06
Quote: "10, an integer, might be stored by DB as 9.87988"

No.
With A# = 10
A# will be stored as 10.0
It is true that it is always better to do the conversion yourself i.e A#=10.0
Or if integer variables:
A# = (myint * 1.0) / (myint2 + 0.0)
This is heavier but safer when not sure about how the types are processed..
You will have truncation on operate large integers:
10000000000+1=10000000000
Because of float 24 bit of precision...
Quote: "I wonder if I have to use trickery like conversion to string then real"


It shouldnot be necessary...

All hail the new flesh
MrValentine
AGK Backer
15
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 3rd Jan 2015 18:47
You have to be careful when playing with floats or integers, it is the one thing that can catch you out that I can think of right now as it did catch me out two days ago... to store fixed floats [that is 10.0, 100.0, 150.0] as integers I had to use the int() function otherwise they are stored as 9.xxxxx something

Minervo
11
Years of Service
User Offline
Joined: 30th Dec 2014
Location: United States
Posted: 4th Jan 2015 03:11
@AGK Backer: Thank you for your reply. Okay, 10 is stored as 9.xxxx. That means that the function int(10) should return 9, but it doesn't.

Minervo
Minervo
11
Years of Service
User Offline
Joined: 30th Dec 2014
Location: United States
Posted: 4th Jan 2015 03:26
I get it that A# = 10 is stored as 10.0. It is safer to do conversions to REAL. I just have never had to do that in any language except DB Pro. It just seems to me that in machine language, it is straightforward to store decimal constant 10 as binary 1010 instead of the binary equiv of the float 9.98897 or whatever. However, I have never designed a language, so I am not qualified to argue, so my statements are moot. Thanks, though. I will get back to my discovery voyage in DB Pro.

Minervo
Kevin Picone
23
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 4th Jan 2015 06:18
Generally compilers give Mult/Div and Add/Subtract have the same level of precedence and therefore resolve within the expressions left to right. So when the expression solver scans an expression, it'd solve mult / divides first regardless of the order in the expression.

DBpro doesn't use this general rule however (From memory neither does DB classic), choosing to perform divisions before mults regardless of the order, the same applies to subtraction, which will be performed before addition.


ie.

print 100*10/15

Sync
wait key

So when it breaks the expression down it's solving 10/15 first (even though the 100*10 is actually first), then multing the result by 100. Since there integer operations we get zero in DBpro.

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 4th Jan 2015 13:26
Quote: "DBpro doesn't use this general rule however (From memory neither does DB classic), choosing to perform divisions before mults regardless of the order"


Yes, that is indeed an anomaly. I hadn't realised DBPro did that.

As far as the issue of inaccuracies arising in float to integer conversions is concerned, my experience is that that problem needs thinking about in every language I've ever used. Generally, never rely on exact integers being returned as the result of a float calculation. Similarly, it is almost never sensible to test for exact equality between floats.



Powered by Free Banners
BatVink
Moderator
23
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 5th Jan 2015 14:25 Edited at: 5th Jan 2015 14:32
DBPro has given the correct answer, with no anomolies:

12-5*12/10-5

The order is Brackets, Orders, Divide, Multiply, Add, Subtract, so it can be written as:

12 - (5*(12/10)) - 5

so...

12 / 10 = 1 (Division of 2 integers = integer result)

therefore

12 - (5*1) - 5 = 2

---------------------------

To get the answer 1, you need to write:

12-5*12/10.0-5

which is the same as

12 - (5*(12/10.0)) - 5

Thus

12 / 10.0 = 1.2 (Division of at least one float = float result)

and therefore

12 - (5*1.2) - 5 = 1


The answer has nothing to do with how floats are stored and processed in DBPro. It's about how numbers are interpreted in the first place. It's very similar to the following in VB:

12 / 10.0 = 1.2
12 \ 10.0 = 1

The syntax determines the interpretation

Quidquid latine dictum sit, altum sonatur

Login to post a reply

Server time is: 2026-07-05 03:50:33
Your offset time is: 2026-07-05 03:50:33