It is currently Wed Jul 24, 2019 9:56 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 43 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 6:49 am 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 866
Currently Sign() returns a float value. In the following example you can see what idiotic results this can lead to:

Code:
Procedure.i MySign (x.f)
  If x > 0
    ProcedureReturn 1
  ElseIf x < 0
    ProcedureReturn -1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

a.i = -349

Debug (a+50*Sign(a))/100*100   ; -399.0
Debug (a+50*MySign(a))/100*100 ; -300

_________________
sorry for my bad english


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 9:26 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 22, 2003 7:43 pm
Posts: 399
Location: Germany, Saarbrücken
You also could use this macro
Code:
Macro SignI(x)
   (Bool((x) > 0) - Bool((x) < 0))
EndMacro

But of course it's not perfect because x gets called twice.

Btw. there is a weird with Bool():
Code:
Debug Bool(0.3 > 0)

Why is the result a float?

_________________
Electronics, Crazy & Interesting Stuff, all that with text, image and sound? Click here!

The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 10:08 am 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 13, 2010 3:45 pm
Posts: 866
NicTheQuick wrote:
Why is the result a float?

Well, Bool is also such a funny command where I really don't know what it's needed for. Is there another programming language that needs it at all? The bad thing is that Bool also produces results that are definitely wrong.

PureBasic is a great language, calculations work in practical use without any problems, but when you go into detail, you come across one problem after another. I'm only talking about basic things like calculations, Pb produces so much crap that you can only shake your head.

Especially with the combination of integers and floats, PB often produces results that are completely arbitrary and often incomprehensible. Fred should start with that and completely revise his Eval so that you can rely on results for basic calculations and don't need workarounds.

Excuse this harsh criticism, but sometimes it just has to come out.

_________________
sorry for my bad english


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 1:55 pm 
Offline
Always Here
Always Here

Joined: Fri Oct 23, 2009 2:33 am
Posts: 5820
Location: Wales, UK
Hi Josh

Debug Sign(a) ; -1.0
Debug MySign(a) ; -1

_________________
IdeasVacuum
If it sounds simple, you have not grasped the complexity.


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 2:47 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 07, 2007 3:25 pm
Posts: 3598
Location: Berlin, Germany
NicTheQuick wrote:
You also could use this macro
Code:
Macro SignI(x)
   (Bool((x) > 0) - Bool((x) < 0))
EndMacro

But of course it's not perfect because x gets called twice.

Here is a macro where x is called only once: :-)
Code:
Macro MySign (x)
   (Bool((x) >= 0)*2 - 1)
EndMacro

; -- Demo
Debug MySign(-7)
Debug MySign( 7)

_________________
Please excuse my flawed English. My native language is PureBasic.
Search
RSBasic's backups


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 2:53 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Jun 07, 2007 3:25 pm
Posts: 3598
Location: Berlin, Germany
NicTheQuick wrote:
Btw. there is a weird with Bool():
Code:
Debug Bool(0.3 > 0)

Why is the result a float?

Yes, that's weird. Has been discussed here before ...

_________________
Please excuse my flawed English. My native language is PureBasic.
Search
RSBasic's backups


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 2:54 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 22, 2003 7:43 pm
Posts: 399
Location: Germany, Saarbrücken
Little John wrote:
Here is a macro where x is called only once: :-)
Code:
Macro MySign (x)
   (Bool((x) >= 0)*2 - 1)
EndMacro

; -- Demo
Debug MySign(-7)
Debug MySign( 7)

But you forgot the Zero. :wink:
Code:
Debug MySign( 0) ; Wrong

_________________
Electronics, Crazy & Interesting Stuff, all that with text, image and sound? Click here!

The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.


Last edited by NicTheQuick on Fri Jul 12, 2019 5:04 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 2:59 pm 
Offline
Addict
Addict
User avatar

Joined: Tue Dec 23, 2003 3:54 am
Posts: 1627
I pretty much agree Josh.

However Sign() has always returned a float (not sure why)
so I honestly doubt it will be changed.

At least the workarounds are simple.

Quote:
But of course it's not perfect because x gets called twice.

How about:
Code:
Macro SignI(Number)
  Int(Sign(Number))
EndMacro


Quote:
Btw. there is a weird with Bool():
Code:
Debug Bool(0.3 > 0)

Why is the result a float?


Ohhh yes. I love Bool() but it has some strange behaviors, we discussed a lot of it here, never resolved:
viewtopic.php?f=4&t=69180

Code:
Debug Bool(0.3 > 0)

x.d = 0.3
Debug Bool(x > 0)


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 6:48 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 2971
Location: Boston, MA
Same as this evil bug :evil: :evil:
Code:
#small1           = 1e-16       ; Epsilon value: small '1' to add to double calcs to round up or prevent overflows.
Macro ML_Tburst_from_PW_DC(PW_s, dc_pc)
  ; PulseWidth(s), DC_pc = DutyCycle(%)
  ; Returns Tburst(s) = Burst period for a given Pulse Width and Duty Cycle
  ; Must force Floating point math with the leading 0.0+ or 1e0.
  (1e0 / ((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1))
EndMacro
Macro ML_Tburst_from_PW_DC_BAD(PW_s, dc_pc)
  ; PulseWidth(s), DC_pc = DutyCycle(%)
  ; Returns Tburst(s) = Burst period for a given Pulse Width and Duty Cycle
  ; Must force Floating point math with the leading 0.0+ or 1e0.
  ; WOW! omitting outer parentheses causes error.
  1e0 / ((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1)
EndMacro
Debug "-- ML_Tburst_from_PW_DC() --"
Debug ML_Tburst_from_PW_DC(20e-6, 10)
Debug 1 / ML_Tburst_from_PW_DC(20e-6, 10)
Debug "-- ML_Tburst_from_PW_DC_BAD(Dropped parentheses) --"
Debug ML_Tburst_from_PW_DC_BAD(20e-6, 10)
Debug 1 / ML_Tburst_from_PW_DC_BAD(20e-6, 10)

_________________
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: Fri Jul 12, 2019 7:05 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jul 23, 2011 1:13 am
Posts: 202
Location: Germany
skywalk wrote:
Same as this evil bug :evil: :evil:
Code:
#small1           = 1e-16       ; Epsilon value: small '1' to add to double calcs to round up or prevent overflows.
Macro ML_Tburst_from_PW_DC(PW_s, dc_pc)
  ; PulseWidth(s), DC_pc = DutyCycle(%)
  ; Returns Tburst(s) = Burst period for a given Pulse Width and Duty Cycle
  ; Must force Floating point math with the leading 0.0+ or 1e0.
  (1e0 / ((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1))
EndMacro
Macro ML_Tburst_from_PW_DC_BAD(PW_s, dc_pc)
  ; PulseWidth(s), DC_pc = DutyCycle(%)
  ; Returns Tburst(s) = Burst period for a given Pulse Width and Duty Cycle
  ; Must force Floating point math with the leading 0.0+ or 1e0.
  ; WOW! omitting outer parentheses causes error.
  1e0 / ((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1)
EndMacro
Debug "-- ML_Tburst_from_PW_DC() --"
Debug ML_Tburst_from_PW_DC(20e-6, 10)
Debug 1 / ML_Tburst_from_PW_DC(20e-6, 10)
Debug "-- ML_Tburst_from_PW_DC_BAD(Dropped parentheses) --"
Debug ML_Tburst_from_PW_DC_BAD(20e-6, 10)
Debug 1 / ML_Tburst_from_PW_DC_BAD(20e-6, 10)


Well, if you get rid of all the comments and specific code, your two examples boil down to this, don't they?

Code:
Debug 1 / 1.0 / 5000.0 ;5000 is the result of "((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1)" for the values given in your example
Debug 1 / (1.0 / 5000.0) ;5000 is the result of "((1.0 / (PW_s) * ((dc_pc) / 100.0)) + #small1)" for the values given in your example


It's not surprising, that "omitting outer parantheses" causes an "error", but both lines procude the correct result for the mathematical term that is presented in them. https://www.wolframalpha.com/input/?i=1 ... F(1%2F5000)



Code:
;Your example commented, again 5000 is the result of the right hand side of the macro calculation where you use or don't use parantheses
Debug "-- ML_Tburst_from_PW_DC() --"
Debug (1e0 / 5000)       ;1/5000 = 0.0002
Debug 1 /  (1e0 / 5000)   ;1/0.0002 = 5000
Debug "-- ML_Tburst_from_PW_DC_BAD(Dropped parentheses) --"
Debug 1e0 / 5000      ;1/5000 = 0.0002
Debug 1 /  1e0 / 5000   ;1 * (1/1) * (1/5000) = 1*1*0.0002 = 0.0002


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

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 2971
Location: Boston, MA
What are you concluding?
The parentheses are required in macro's to allow complex parameter entries and ensure the correct order of math operations.
2 + 2 does not need parentheses.
But in a complex macro(a,b)
(a) + (b) does.

If I drop the leading 1e0 and use 1, then the answer is also wrong.
If I place a leading '0.0 + ' then that gives correct answer.
Just the pains of using swift PureBasic! :evil:

_________________
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: Fri Jul 12, 2019 7:34 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Jul 23, 2011 1:13 am
Posts: 202
Location: Germany
I'm concluding that your two macros resolve to a/b/c and a/(b/c) and that those are mathematically different.


Top
 Profile  
Reply with quote  
 Post subject: Re: Sign() has to return an integer result
PostPosted: Fri Jul 12, 2019 8:56 pm 
Offline
Addict
Addict
User avatar

Joined: Tue Dec 23, 2003 3:54 am
Posts: 1627
Yeah, the "bad" calculation is a result of dangerously written macros, not a PB bug. The same thing would happen in C, etc.

Code:
Macro Invert(x) ; safe macro
  (1.0 / (x))
EndMacro

Macro Invert_Wrong1(x) ; missing outer parentheses!
  1.0 / (x)
EndMacro

Macro Invert_Wrong2(x) ; missing parentheses around parameter!
  (1.0 / x)
EndMacro


four.d = 4.0
Debug 1.0 / Invert(four / 2.0)        ; correct - gives 2.0
Debug 1.0 / Invert_Wrong1(four / 2.0) ; wrong - gives 0.5
Debug 1.0 / Invert_Wrong2(four / 2.0) ; wrong - gives 8.0
; but these are macro mistakes, not PB bugs


Also I don't understand where you are inserting 0.0 to fix the calculation?


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

Joined: Thu Jun 07, 2007 3:25 pm
Posts: 3598
Location: Berlin, Germany
NicTheQuick wrote:
But you forgot the Zero. :wink:
Code:
Debug MySign( 0) ; Wrong

Ooops. :oops:
You are right, of course.

_________________
Please excuse my flawed English. My native language is PureBasic.
Search
RSBasic's backups


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

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 2971
Location: Boston, MA
Yes, this explains it! Thanks Kenmo, Derren
The macro without outer parentheses works on assignment, but not inline another equation.
I write these examples to educate myself. :oops:
The '0.0 +' was not needed here since exponents in the parameters trigger floating operations.
It is needed below :wink: :evil:
Code:
Procedure.i MySign (x.f)
  If x > 0
    ProcedureReturn 1
  ElseIf x < 0
    ProcedureReturn -1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure
a.f = -3
Debug "-- PB    mixed type multiplication & division --"
Debug Sign(a)/100*100  ; -1.0
Debug MySign(a)/100*100; 0
Debug "-- 0.0 + mixed type multiplication & division --"
Debug 0.0+Sign(a)/100*100  ; -1.0
Debug 0.0+MySign(a)/100*100 ; -1.0

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


Last edited by skywalk on Sun Jul 14, 2019 5:13 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 43 posts ]  Go to page 1, 2, 3  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 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