Page 1 of 1

Sign of double

Posted: Sat Apr 17, 2004 3:33 am
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 

Posted: Sat Apr 17, 2004 9:43 am
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)

Posted: Sat Apr 17, 2004 4:05 pm
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.