Sign of double

Share your advanced PureBasic knowledge/code with the community.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Sign of double

Post by jack »

Code updated for 5.20+ (same as Sign())

i think this will be of interest, i started with this procedure:

Code: Select all

Procedure Sign_(*x.double)   ;returns -1 if x<0,  0 if x=0,  1 if x>0,  2 if fperror
  ! mov edx,[esp]
  ! fld qword [edx]
  ! ftst
  ! fnstsw ax
  ! sahf
  ! jp fperror
  ! je fpequals
  ! jb x_isless_y
  ! ja x_isgreater_y
  !fperror:
  ! mov eax,2
  ! jmp Fsign_end
  !fpequals:
  ! mov eax,0
  ! jmp Fsign_end
  !x_isless_y:
  ! mov eax,-1
  ! jmp Fsign_end
  !x_isgreater_y:
  ! mov eax,1
  !Fsign_end:
  ProcedureReturn
EndProcedure
i did not like all the jumps, and asked for help in the masm forum, here's what Paul Dixon came up with.

Code: Select all

Procedure Sign_(*x.double)   ;returns -1 if x<0,  0 if x=0,  1 if x>0
;by Paul Dixon
! mov edx,[esp]
! fld qword [edx] 
! ftst 
! fstsw ax 
! mov al,ah 
! shr al,6      
! xor ah,1  
! xor ah,al 
! shl ah,1 
! Or al,ah 
! And eax,3 
! dec eax
ProcedureReturn
EndProcedure 
Pupil
Enthusiast
Enthusiast
Posts: 715
Joined: Fri Apr 25, 2003 3:56 pm

Post by Pupil »

You can also try this, uses only integer ASM op:s... try it out thoroughly before using in any app as i've only made a few isolated test runs with it...

Code: Select all

Procedure.l Sgn(address.l)
  ; Input need to be an address to a double!
  MOV ebp, [esp]
  MOV ebx, [ebp+4]
  MOV eax, [ebp]
  XOR edx, edx
  BTR ebx, 31
  SETNC dl
  XOR ecx, ecx
  AND eax, eax
  SETZ al
  AND ebx, ebx
  SETZ cl
  OR cl, al
  DEC ecx
  MOV eax, ecx
  AND eax, 1
  DEC edx
  AND edx, ecx
  OR eax, edx
  ProcedureReturn
EndProcedure

; Test code
Structure double
  l.l
  h.l
EndStructure

a.f = -3.14159265
b.double
!fld dword [v_a]
!fst qword [v_b]

debug Sgn(@b)
Road Runner
User
User
Posts: 48
Joined: Tue Oct 07, 2003 3:10 pm

Post by Road Runner »

Code: Select all

Procedure Sign(*x.double)   ;returns -1 if x<0,  0 if x=0,  1 if x>0,  2 if fperror 
Procedure Sign(*x.double)   ;returns -1 if x<0,  0 if x=0,  1 if x>0 
The second one also gives 2 if there is an error in the comparison.
Post Reply