Unsigned variable bug

Just starting out? Need help? Post your questions and find answers here.
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Unsigned variable bug

Post by User_Russian »

In this code a-4=254. But they are calculated as signed variables. Why?

Code: Select all

a.a = 2
b.a = a-4
Debug b
Debug Bool(a-4>0)
If a-4>0
  Debug "a>0"
EndIf
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Unsigned variable bug

Post by Little John »

User_Russian wrote:In this code a-4=254. But they are calculated as signed variables. Why?

Code: Select all

a.a = 2
b.a = a-4
Debug b
Debug Bool(a-4>0)
If a-4>0
  Debug "a>0"
EndIf
No, b is calculated as unsigned variable, that's why Debug b shows 254 (PB 5.71 beta 3).
If b were calculated as signed variable, Debug b would show -2.

I can't see any bug there.
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Unsigned variable bug

Post by mk-soft »

This is normal binary calculation with over and underflow of values.
You have to take care to calculate in the right range.

No Bug 8)
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User_Russian
Addict
Addict
Posts: 1443
Joined: Wed Nov 12, 2008 5:01 pm
Location: Russia

Re: Unsigned variable bug

Post by User_Russian »

If the variable is unsigned (the variable a is unsigned), the calculations must be unsigned.
Why are signed calculations performed for an unsigned variable?
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Unsigned variable bug

Post by Little John »

User_Russian wrote:If the variable is unsigned (the variable a is unsigned), the calculations must be unsigned.
Who says so (except from you)?
I think the terms "signed" and "unsigned" apply when values are assigned to the respective variable, not when using it in calculations.
User avatar
STARGÅTE
Addict
Addict
Posts: 2084
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Unsigned variable bug

Post by STARGÅTE »

The comparison operators in PB are always signed, independent from the variable type.
You have to use ASM like this:

Code: Select all

Procedure AboveByte(a.a, b.a)
	!MOV cl, [p.v_a]
	!MOV dl, [p.v_b]
	!CMP cl, dl
	!JNA @F
	ProcedureReturn 1
	!@@:
	ProcedureReturn 0
EndProcedure

a.a = 2
b.a = a-4
Debug b
Debug Bool(AboveByte(a-4,0))
If AboveByte(a-4,0)
  Debug "a>0"
EndIf
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Unsigned variable bug

Post by Little John »

Or first assign the result of an expression to an unsigned variable, and then use that variable for comparisons, rather than the original expression itself:

Code: Select all

a.a = 2
b.a = a-4
Debug b
Debug Bool(b > 0)
If b > 0
   Debug "b > 0"
EndIf
BTW: Wilbert posted code for doing unsigned comparisons:
viewtopic.php?p=419868#p419868
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Unsigned variable bug

Post by mk-soft »

Link Unsigned: viewtopic.php?f=12&t=73280

Code: Select all

Macro Unsigned (_value_)
   (((1 << (8*SizeOf(_value_))) - 1) & _value_)
EndMacro

a.a = 2
b.a = a-4
Debug b
Debug Bool(b > 0)
If Unsigned(b) > 0
   Debug "b > 0"
EndIf
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
idle
Always Here
Always Here
Posts: 5088
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Unsigned variable bug

Post by idle »

I'd call it a bug the Bool and If should do an unsigned comparison

Code: Select all

;EnableUnsigned  v1.0a   
;Author Idle 25/3/16 
;Supports PB 5.42LTS Window, Linux  
;Unsigned arithmetic and logical comparisons for   
;x64: Long, Integer, Quads 
;x86: Long, Integer 
;Usage: 
;Scope unsigned arithmetic and logic in EnableUnsigned() DisableUnsigned() blocks
;EnableUnsigned()  
;if ux > uy  ; changes the operators to unsigned: supports < > <= >= <> =   
;    do something unsigned: supports * / + - << >>  
;  DisableUnsigned()
;   ;back to signed  
;EndIf 
;Disableunsigned() ;Note you can call Disableunsigned() where ever you need it 


CompilerIf SizeOf(integer) = 4
  
  
Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !mov edx,0 
     !div var
  !}
  
  !macro IMUL reg,var
  !{
    !mov eax,reg 
    !mul var
    !mov reg,eax 
  !}  
  
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
    
  !macro CDQ {} 
  
  !macro JG arg
  !{ 
  !JA arg 
  !}
  !macro JGE arg 
  !{ 
     !JAE arg 
  !}
  !macro JL arg 
  !{
     !JB arg 
  !}
  !macro JLE arg 
  !{ 
     !JBE arg 
  !}
  
EndMacro

Macro DisableUnsigned() 
  !purge IDIV
  !purge IMUL
  !purge SAR
  !purge SAL 
  !purge CDQ 
  !purge JG
  !purge JGE
  !purge JL
  !purge JLE
EndMacro 

CompilerElse 
   
  Macro EnableUnsigned() 
  
  !macro IDIV var
  !{ 
     !mov rdx,0 
     !div var
  !}
  
  !macro IMUL reg,var
  !{
  !match =qword x , var 
  !\{ mov rax, reg 
     !mov r15, var 
   !\} 
    !mul reg
    !mov reg,rax 
  !}  
  
  !macro SAR reg,var 
  !{
    !shr reg,var 
  !} 
  
  !macro SAL reg,var 
  !{ 
   !shl reg,var 
  !}
    
  !macro MOVSXD reg,var  
  !{ 
    !match =dword x , var 
    !\{ mov eax, var 
       !mov reg,rax \} 
    !} 
  !macro CQO {}
  !macro CDO {}
  !macro CWD {} 
  !macro CBW {}
  !macro CWDE{}
  !macro CDQE {} 
  !macro CDQ {} 
  
  !macro JG arg
  !{ 
  !JA arg 
  !}
  !macro JGE arg 
  !{ 
     !JAE arg 
  !}
  !macro JL arg 
  !{
     !JB arg 
  !}
  !macro JLE arg 
  !{ 
     !JBE arg 
  !}
  
EndMacro 

Macro DisableUnsigned() 
  !purge IDIV
  !purge IMUL
  !purge SAR
  !purge SAL 
  !purge MOVSXD
  !purge CQO 
  !purge CDO
  !purge CWD 
  !purge CBW
  !purge CWDE 
  !purge CDQE 
  !purge CDQ 
  !purge JG
  !purge JGE
  !purge JL
  !purge JLE
EndMacro   

CompilerEndIf   


a.a = 2
b.a = a-4   
Debug b

EnableUnsigned()
Debug Bool(a-4>0)
If a-4>0
  Debug "a>0"
EndIf
Windows 11, Manjaro, Raspberry Pi OS
Image
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Unsigned variable bug

Post by Little John »

idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
As far as I can see, doing always signed comparison is the intended behaviour (as Stargate already wrote). So it can hardly be called a bug.
Asking for unsigned comparison in particular cases is a feature request.
User avatar
Demivec
Addict
Addict
Posts: 4089
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Unsigned variable bug

Post by Demivec »

Little John wrote:
idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
As far as I can see, doing always signed comparison is the intended behaviour (as Stargate already wrote). So it can hardly be called a bug.
Asking for unsigned comparison in particular cases is a feature request.
In addition, IMHO the sample code is a worthless example:

Code: Select all

a.a = 2
b.a = a-4
Debug Bool(a-4>0) ;How is Bool() supposed to know you want an unsigned comparison?
If a-4>0          ;How is IF supposed to know you want an unsigned comparison?
If the comparison 'a-4 > 0' is to be treated as unsigned it should be rewritten as 'a-4 <> 0'.
User avatar
idle
Always Here
Always Here
Posts: 5088
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Unsigned variable bug

Post by idle »

Demivec wrote:
Little John wrote:
idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
As far as I can see, doing always signed comparison is the intended behaviour (as Stargate already wrote). So it can hardly be called a bug.
Asking for unsigned comparison in particular cases is a feature request.
In addition, IMHO the sample code is a worthless example:

Code: Select all

a.a = 2
b.a = a-4
Debug Bool(a-4>0) ;How is Bool() supposed to know you want an unsigned comparison?
If a-4>0          ;How is IF supposed to know you want an unsigned comparison?
If the comparison 'a-4 > 0' is to be treated as unsigned it should be rewritten as 'a-4 <> 0'.
@little john
a is unsigned so the cmp should treated as such

@demivec

or just use & $ff

Code: Select all

a.a = 2
b.a = a-4   
Debug b

Debug Bool(((a-4) & $ff)>0)
If ((a-4) & $ff) > 0
  Debug "a>0"
EndIf


One thing that's not clear is the documentation, otherwise the OP wouldn't have asked the question
and yes I do think it's a bug as .a and .u are only kind of unsigned it should extend to logic operators
Windows 11, Manjaro, Raspberry Pi OS
Image
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Unsigned variable bug

Post by #NULL »

Everybody talks about the comparison operation, but there is the subtraction before that. Why is it more logical to convert the 4 to unsigned to match the type of .a than to convert the .a to singed? Often in languages both operand are converted to the larger type present, but mixing signedness is usually a bad idea anyway.
Little John
Addict
Addict
Posts: 4527
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Unsigned variable bug

Post by Little John »

idle wrote: @little john
a is unsigned so the cmp should treated as such
When a = 2, then treating the expression a-4 as unsigned should result in an error, strictly speaking. Because 2-4 is -2, which is out of the "unsigned" range. Fred decided that the compiler does not raise an error in cases like this, but handles the result of this expression as a signed value instead. That's completely legal.

What should be done in the first place is this: Do not subtract x from an unsigned variable that has value y, when x > y, so that the result would be < 0.
mk-soft wrote:You have to take care to calculate in the right range.
User avatar
mk-soft
Always Here
Always Here
Posts: 5386
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Unsigned variable bug

Post by mk-soft »

It's also good that Fred doesn't intercept this.

In some cases it is normal to expect overflow.
Especially in case of difference calculations of infinite counters, because they generate a normal overflow at some point.

Therefore I was very excited when the function "ElapsedMilliseconds" was changed, because a difference calculation ALWAYS leads to a correct result when an overflow occurs.

Many didn't understand that.

Translated with www.DeepL.com/Translator
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply