# PureBasic Forum

 It is currently Sat Oct 19, 2019 2:37 pm

 All times are UTC + 1 hour

 Page 2 of 3 [ 43 posts ] Go to page Previous  1, 2, 3  Next
 Print view Previous topic | Next topic
Author Message
 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 2:01 pm
 Enthusiast

Joined: Sat Jul 23, 2011 1:13 am
Posts: 217
Location: Germany
Well, with this code, your 0.0+ is needed to mimmick the faulty PB sign() function. (and by "faulty" I mean that it returns a float (or perhaps ad double? I don't know)

In PB, a float conversion in a division is started when either a or b in a/b are floats.
You could just change your MySign() procedure to return a float (or double).

Regardless, the integers 1 or 0 or -1 divided by 100 will always be 0 and 0 times 100 is 0.
This is the known behaviour with integers. There is no automatic casting to float, even if you write x.f = a/b

Knowing this, you can either let MySign() return a float, or write MySign()/100.0 instead of /100
No need for the 0.0+

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 3:01 pm

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
Derren wrote:
In PB, a float conversion in a division is started when either a or b in a/b are floats.

And that's the next problem. In PureBasic this is only partly true. In different programming languages there are two paradigms:

• In the first one the result is a float, if one of the operands is a float. This is for example the case in C, C++, C# or Java.
• In the other, everything is always calculated in float. That is for example the case in VB, Lua or Pascal.
• Then there is PureBasic. You can't speak of a paradigm, because it simply doesn't have a continuous system. Pb works sometimes after the first point, sometimes after the second point and sometimes Pb does something completely different, which I can't understand with the best will in the world.

I took the trouble to do some calculations in different programming languages. You can see the result here:
Code:
+------------------------------------+------+------+------+
|                                    |C, C++|  VB  |  PB  |
|                                    | C#   | LUA  |      |
|                                    | Java |  JS  |      |
|                                    | D    |PASCAL|      |
|                                    |PYTHON|PYTHO3|      |
|                                    | RUBY | PERL |      |
|                                    |  GO  | PHP  |      |
+------------------------------------+------+------+------+
| 3/5                                |  0.0 |  0.6 |  0.0 |
| 3.0/5                              |  0.6 |  0.6 |  0.6 |
| 3/5.0                              |  0.6 |  0.6 |  0.6 |
| (3/3/3/3.0)*(3*3*3)                |  0.0 |  3.0 |  3.0 |
| (5/2+3/3/3/3.0)*(3*3*3)            | 54.0 | 70.5 | 57.0 |
| (5.0/2+3/3/3/3.0)*(3*3*3)          | 67.5 | 70.5 | 70.5 |
+------------------------------------+------+------+------+
Note especially the penultimate calculation.

It is really hard to see, that PB fails with simple basic calculations.

_________________
sorry for my bad english

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 3:30 pm

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 3083
Location: Boston, MA
I brought this up over 10 years ago when I stumbled into this behavior.
I was shouted down back then since my recommendation would slow down integer math.
So I asked for a compiler OPTION to make ALL division floating point.
But that was also shouted down as too many options. hahahahaha
Instead, we continue with intuitive math. You must use your PB intuition.

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 4:03 pm

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
skywalk wrote:
So I asked for a compiler OPTION to make ALL division floating point.
This isn't about PB turning a division into a float. For me the system C, C++ etc. would be absolutely ok, if PB would stick to it.

It's just that PB simply does what it wants, that PB delivers faulty calculations and has no clear line for calculations.

_________________
sorry for my bad english

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 4:11 pm
 Enthusiast

Joined: Sat Jul 23, 2011 1:13 am
Posts: 217
Location: Germany
Josh wrote:
Code:
+------------------------------------+------+------+------+
|                                    |C,etc |  VB  |  PB  |
+------------------------------------+------+------+------+
| 3/5                                |  0.0 |  0.6 |  0.0 |
| 3.0/5                              |  0.6 |  0.6 |  0.6 |
| 3/5.0                              |  0.6 |  0.6 |  0.6 |
| (3/3/3/3.0)*(3*3*3)                |  0.0 |  3.0 |  3.0 |
| (5/2+3/3/3/3.0)*(3*3*3)            | 54.0 | 70.5 | 57.0 |
| (5.0/2+3/3/3/3.0)*(3*3*3)          | 67.5 | 70.5 | 70.5 |
+------------------------------------+------+------+------+

Right, so if you keep in mind, that a.i/b.i will always be handled as ceil(a.f/b.f), every single calculation is correct in PB.

I can't figure out, how the result of 54.0 and 76.5 is created in the first result column. Can somebody explain?
Either way, I think those results are wrong.

Here I will resolve the integer/integer calculations to their respective results. If you then proceed to calculate, you will see how PB gets its results and again, Wolfram Alpha will show that it's correct.

Code:
+------------------------------------+------+------+------+
|                                    |C,etc |  VB  |  PB  |
+------------------------------------+------+------+------+
| "0"                                |  0.0 |  0.6 |  0.0 |
| 3.0/5                              |  0.6 |  0.6 |  0.6 |
| 3/5.0                              |  0.6 |  0.6 |  0.6 |
| (3/3/3/3.0)*(3*3*3)                |  0.0 |  3.0 |  3.0 |
| ("2"+3/3/3/3.0)*(3*3*3)            | 54.0 | 70.5 | 57.0 |
| (5.0/2+3/3/3/3.0)*(3*3*3)          | 67.5 | 70.5 | 70.5 |
+------------------------------------+------+------+------+

Don't compare with what other languages are doing, compare with your own math and keep in mind, that a/b is rounded down.

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 4:27 pm

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
Derren wrote:
I can't figure out, how the result of 54.0 and 76.5 is created in the first result column. Can somebody explain?

Thats easy:
Code:
(5/2+3/3/3/3.0) * (3*3*3)
(5/2+3/3/3/3.0) * ( 27  )
( 2 +3/3/3/3.0) * ( 27  )
( 2 +3/3/3/3.0) * ( 27  )
( 2 + 1 /3/3.0) * ( 27  )
( 2 +   0 /3.0) * ( 27  )
( 2 +   0.0   ) * ( 27  )
(    2.0      ) * ( 27  )
(        54.0           )

All results in the first two columns are absolutely correct, there are simply two different paradigms of how to deal with floats. Only PB has no system and gives wrong results.

Derren wrote:
Right, so if you keep in mind, that a.i/b.i will always be handled as ceil(a.f/b.f), every single calculation is correct in PB.
No, please read what I habe written. The result of 57.0 is definitely bullshit.

_________________
sorry for my bad english

Last edited by Josh on Sat Jul 13, 2019 4:35 pm, edited 1 time in total.

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 4:35 pm
 Enthusiast

Joined: Sat Jul 23, 2011 1:13 am
Posts: 217
Location: Germany
So the issue is this:

What do I need to put in my code, to get a/b/c as a float:

In PB: 1.0*a/b/c
In C: 1.0*a/(1.0)*b/c

It IS consistent. If at least one part of a multiplication is a float, the whole calculation is casted to float.
That doesn't seem to be the case with the C-type languages, as you just demonstrated, as 1/3/3.0 yields 0/3.0 = 0 instead of 1/(3*3.0) = 1/9 as PB does.
But that means that the C-type calculation is a simple "from left right" and does not see past the current operation.

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 5:08 pm

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
Derren wrote:
In C: 1.0*a/(1.0)*b/c
Where do you get this nonsense? 1.0*a/b/c is absolutly ok in C

Derren wrote:
It IS consistent.
It IS NOT consistent in PureBasic.

Derren wrote:
If at least one part of a multiplication is a float, the whole calculation is casted to float.
That's it. You said it. If one part of a multiplication is a float, then the result is also a float. Emphasis is on ONE PART of the calculation and not ANY PART in a term.

Derren wrote:
But that means that the C-type calculation is a simple "from left right" and does not see past the current operation.
This is the way. Terms are resolved from left to right. This is handled by all programming languages that use this paradigm and this is the only correct way in this case.

PureBasic alone does something else, that it just comes out of nonsense, you can see in my examples above or e.g. here:
Code:
Debug (5/2 + 3/3/3/3.0) ; 2.1111111111111112
Debug (3/3/3/3.0 + 5/2) ; 2.6111111111111112

_________________
sorry for my bad english

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 6:14 pm

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 3083
Location: Boston, MA
Ultimately, we have a compiler option to force float math.
Use '0.0 +' prefix until PB goes LLVM or massive ASM rewrites.

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 7:49 pm

Joined: Fri May 12, 2006 6:51 pm
Posts: 1968
Location: Germany
Only the debugger output is inaccurate, because the typefitting doesn't work right here.
Code:
a.f = (5/2 + 3/3/3/3.0) ; 2.1111111111111112
b.f = (3/3/3/3.0 + 5/2) ; 2.6111111111111112

Debug a
Debug b

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 9:21 pm

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
mk-soft wrote:
Only the debugger output is inaccurate, because the typefitting doesn't work right here.

At first I was happy that there was such a simple explanation and the bug occurs only in debugger mode. But unfortunately this is not the case, it makes PB's calculation system even more catastrophic.

It seems that PB makes the calculation of the term dependent on the type of target variable. This is, of course, complete nonsense. A term should be calculated and then the result should be casted to the type of the target variable. Then it could also not be that one and the same calculation bring different results:

Code:
Debug 1.0 + 5/2
Debug 5/2 + 1.0

Debug "-----"

a.d = 1.0 + 5/2
b.d = 5/2 + 1.0
Debug a
Debug b

Debug "-----"

#a = 1.0 + 5/2
#b = 5/2 + 1.0
Debug #a
Debug #b

Debug "-----"

If 1.0 + 5/2 = 3.5
Debug "3.5"
EndIf

If 5/2 + 1.0 = 3
Debug "3"
EndIf

_________________
sorry for my bad english

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sat Jul 13, 2019 11:52 pm
 Enthusiast

Joined: Sat Jul 23, 2011 1:13 am
Posts: 217
Location: Germany
I was gonna reply to your statements one at a time, until I read this:

Josh wrote:
PureBasic alone does something else, that it just comes out of nonsense, you can see in my examples above or e.g. here:
Code:
Debug (5/2 + 3/3/3/3.0) ; 2.1111111111111112
Debug (3/3/3/3.0 + 5/2) ; 2.6111111111111112

Well, thank you. that IS inconsistent. and now I get where you're coming from, when you say "one float in the term". I guess we'll have to thank the single pass compiler for that one...
Then again, that's the reason why most languages have functions to cast terms to int or float... and why JS is hated for this:
Code:
a = 1 + "1" // a = "11"
a = 1-"1" // a= 0

btw: What I call an inconsistency is this...

Code:
Debug  2/2/3.0
Debug  2/3/3.0

For a=2 To 3
Debug  2/a/3.0
Next

Why on earth is 2/a/3.0 equal to zero, when a =3?? (also the case outside of a for-loop)

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sun Jul 14, 2019 2:06 am

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 907
Derren wrote:
Why on earth is 2/a/3.0 equal to zero, when a =3?? (also the case outside of a for-loop)

Because it's the only correct result:

Code:
a = 2
2/a/3.0
1 /3.0
0.333...

a = 3
2/a/3.0 ; no float in 2/3, so the result is an integer
0 /3.0 ; one float in 0/3.0, so the result is an float
0.0
The term 2/3/3.0 is the bad one that delivers with 0.22222 the wrong result.

Derren wrote:
I guess we'll have to thank the single pass compiler for that one...
No, this has nothing to do with the single pass compiler. For Fred, it would have been even easier if he did not make this look forward.

It's happened to me twice before that a small change to the code (where everyone would say that this shouldn't have any effect on the result) caused errors in my program. Of course, the errors of the wrong calculation then occur in a completely different place in the code. That was 2x half a day for debugging, just because PB has problems with calculating.

_________________
sorry for my bad english

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sun Jul 14, 2019 4:13 am

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 3083
Location: Boston, MA
Do important math in double and prefix 0.0 +.
This saved me many times.

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum

Top

 Post subject: Re: Sign() has to return an integer resultPosted: Sun Jul 14, 2019 8:52 am

Joined: Fri May 12, 2006 6:51 pm
Posts: 1968
Location: Germany
I've learned that you can't mix different number systems.

In the past this was not allowed and today you don't know how the different compilers implement them.
So always convert the types yourself before you use it.

Code:
a.i = (5/2 + 3/3/3/3.0) ; 2.1111111111111112
b.i = (3/3/3/3.0 + 5/2) ; 2.6111111111111112
Debug a
Debug b

This also results in a wrong result at "b".

For me the result is (3/3/3) = 0, so (3/3/3/3.0) is also 0.
For me (5/2) = 2

So do not mix number system!

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 2 of 3 [ 43 posts ] Go to page Previous  1, 2, 3  Next

 All times are UTC + 1 hour

#### Who is online

Users browsing this forum: No registered users and 0 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forum

Search for:
 Jump to:  Select a forum ------------------ PureBasic    Coding Questions    Game Programming    3D Programming    Assembly Programming    The PureBasic Editor    The PureBasic Form Designer    General Discussion    Feature Requests and Wishlists    Tricks 'n' Tips Bug Reports    Bugs - Windows    Bugs - Linux    Bugs - Mac OSX    Bugs - Documentation OS Specific    AmigaOS    Linux    Windows    Mac OSX Miscellaneous    Announcement    Off Topic Showcase    Applications - Feedback and Discussion    PureFORM & JaPBe    TailBite