News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

floating sign test

Started by korte, March 22, 2009, 12:02:37 PM

Previous topic - Next topic

jj2007

Quote from: raymond on March 23, 2009, 02:27:56 AM
Just to be picky based on another discussion regarding overwriting a register vs not overwriting it, how about the following (and we really want to know the SIGN, don't we??? thus making the source code a bit more legible)

Code:
FSIGN MACRO rval:REQ
   mov eax, dword ptr [rval-4+sizeof rval]   ; 5 bytes
   test eax, eax            ; 2 bytes
   exitm <Sign?>
ENDM

Raymond, I love it when you are getting picky :bg
But you may remember that in that historic debate about register-damaging programming practices the "mov" instruction was generally considered "destructive" and, worse, accused of changing register contents ::)
In a spirit of damage limitation, I therefore propose this variant:

Fsign MACRO rval:REQ ; usage: .if FSIGN(MyRealVar)
push eax
mov eax, dword ptr [rval-4+sizeof rval]
test eax, eax
pop eax
exitm <Sign?>
ENDM


While it certainly wastes valuable resources, it has the practical merit that noobs in general don't expect eax to be trashed after a harmless .if Sign?, pardon: .if Fsign()
:bg

Jimg

Building on everyone else's work,
Is there some reason you can't just use-

FSIGN MACRO rval:REQ
   test dword ptr [rval-4+sizeof rval],80000000h
   exitm <Sign?>
ENDM

?
or if you want smaller,
FSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM

jj2007

Quote from: Jimg on March 23, 2009, 02:14:16 PM
Building on everyone else's work,
Is there some reason you can't just use-

...
or if you want smaller,
FSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM


Fantastic - 7 bytes, no registers trashed... :clap:

PBrennick

The GeneSys Project is available from:
The Repository or My crappy website

raymond

Just to prove that 10 heads are better than 9!!! :dance: :clap: :toothy

The way it developed, this thread should have been in the lab.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

jj2007

Quote from: raymond on March 24, 2009, 03:37:45 AM
Just to prove that 10 heads are better than 9!!! :dance: :clap: :toothy

You are right, but it's the exception from the rule "A committee is the only known animal with ten stomachs and no brain" :wink

jj2007

#21
Something was missing, here it is:

FSIGN MACRO rval
  ifb <rval>
    fst real8 ptr [esp-8]
    test byte ptr [esp-8+7], 80h ;; usage for sign of ST0: .if FSIGN()
  else
    test byte ptr [rval-1+sizeof rval], 80h ;; usage:  .if FSIGN(MyRealVar)
  endif
  EXITM <Sign?>
ENDM


Full test attached.

[attachment deleted by admin]

GregL

Quote from: JimgFSIGN MACRO rval:REQ
   test byte ptr [rval-1+sizeof rval],80h
   exitm <Sign?>
ENDM

Very nice.  :thumbu


jj2007

Quote from: Greg on March 24, 2009, 05:23:45 PM

Very nice.  :thumbu


Thanx to the whole team ;-)

Try the slightly extended version above - marginally more complex, but you can use .FSIGN() to test the current FPU content. And it even works for dwords, qwords and tbytes :bg

raymond

QuoteSomething was missing, here it is:

That's a nice extension but there's no need to store the float on the stack as a REAL8. The sign bit will be the same, and always in the most significant bit, whether the float is stored as a REAL4, a REAL8 or a REAL10.

    fst dword ptr [esp-4]
    test byte ptr [esp-4+3], 80h
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

herge

 Hi jj2007:

The results from my computer are in!

---- Test local vars:

Loc4pos is positive
Loc4minus is negative
Loc4zeroA is positive
Loc4zeroB is negative

Loc8pos is positive
Loc8minus is negative
Loc8zeroA is positive
Loc8zeroB is negative

---- Test ST(0):

r10pos   is positive
r10minus is negative
r10zeroA is positive
r10zeroB is negative

---- Test global real variables:

r4pos   is positive
r4minus is negative
r4zeroA is positive
r4zeroB is negative

r8pos   is positive
r8minus is negative
r8zeroA is positive
r8zeroB is negative

r10pos   is positive
r10minus is negative
r10zeroA is positive
r10zeroB is negative


Regards herge

// Herge born  Brussels, Belgium May 22, 1907
// Died March 3, 1983
// Cartoonist of Tintin and Snowy

jj2007

Quote from: raymond on March 25, 2009, 01:19:05 AM
The sign bit will be the same, and always in the most significant bit, whether the float is stored as a REAL4, a REAL8 or a REAL10.


Thanks for confirming that, Raymond, I was a bit uncertain about that hypothetical case where ST is a very small negative number, e.g. 1e-300, the rounding flags are set the wrong direction etc....

raymond

Quotehypothetical case where ST is a very small negative number, e.g. 1e-300, the rounding flags are set the wrong direction etc....

The rounding flag is immaterial. As for your concern, it should have been the same for converting from REAL10 to REAL8 for very small or large numbers.

If too small, the sign bit remains the same but would become +0 or -0.
If too large, the sign bit remains the same but would become +INFINITY or -INFINITY.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com