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
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).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
Who says so (except from you)?User_Russian wrote:If the variable is unsigned (the variable a is unsigned), the calculations must be unsigned.
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
Code: Select all
a.a = 2
b.a = a-4
Debug b
Debug Bool(b > 0)
If b > 0
Debug "b > 0"
EndIf
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
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
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.idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
In addition, IMHO the sample code is a worthless example:Little John wrote: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.idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
Asking for unsigned comparison in particular cases is a feature request.
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?
@little johnDemivec wrote:In addition, IMHO the sample code is a worthless example:Little John wrote: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.idle wrote:I'd call it a bug the Bool and If should do an unsigned comparison
Asking for unsigned comparison in particular cases is a feature request.If the comparison 'a-4 > 0' is to be treated as unsigned it should be rewritten as 'a-4 <> 0'.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?
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
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.idle wrote: @little john
a is unsigned so the cmp should treated as such
mk-soft wrote:You have to take care to calculate in the right range.