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

All times are UTC + 1 hour




Post new topic Reply to topic  [ 43 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 2:01 pm 
Offline
Enthusiast
Enthusiast
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 3:01 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 3:30 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 4:03 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 4:11 pm 
Offline
Enthusiast
Enthusiast
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 4:27 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 4:35 pm 
Offline
Enthusiast
Enthusiast
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 5:08 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 6:14 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 7:49 pm 
Offline
Addict
Addict
User avatar

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
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 9:21 pm 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sat Jul 13, 2019 11:52 pm 
Offline
Enthusiast
Enthusiast
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sun Jul 14, 2019 2:06 am 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sun Jul 14, 2019 4:13 am 
Offline
Addict
Addict
User avatar

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
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Sun Jul 14, 2019 8:52 am 
Offline
Addict
Addict
User avatar

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
Downloads on my Webspace


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 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 forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye