News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Area of a Cirlce problem

Started by infoMASM, March 14, 2014, 07:08:11 PM

Previous topic - Next topic

raymond

QuoteSo where did I misinterpret Rule #1?

Rule #1: An FPU 80-bit register compartment MUST be free (empty) in order to load a value into it.

Whenever the FPU is instructed to load another value, it first brings st(7) to the top before attempting the load, without checking if it is free or not. If st(7) HAD been free, the load is successful; otherwise, st(0) now becomes trash.
Whenever you assume something, you risk being wrong half the time.
http://www.ray.masmcode.com

jj2007


Gunther

Quote from: raymond on March 15, 2014, 02:08:14 PM
Rule #1: An FPU 80-bit register compartment MUST be free (empty) in order to load a value into it.

Whenever the FPU is instructed to load another value, it first brings st(7) to the top before attempting the load, without checking if it is free or not. If st(7) HAD been free, the load is successful; otherwise, st(0) now becomes trash.

Raymond is right. He describes a stack rollover.

Gunther
You have to know the facts before you can distort them.

jj2007

Quote from: Gunther on March 15, 2014, 10:57:41 PM
Raymond is right. He describes a stack rollover.

If your FPU is full, and you want to use fld MyReal8, what do you do before the fld?
a) ffree st(7)
b) ffree st(0)

Hint: only one answer is correct 8)

dedndave


Force

Hi Raymond

I am trying to make a Ftoa

isn't that  simpliest way for it?


Values :

.data
buf db 50 dup (?)
result db 50 dup (?)
n dd 0
mlt dd 100

val1  dd -125.56
val2  dd 68.9
val   dd 0


and code

fld val1
fld val2
fadd st(0),st(1)
fst val


fimul mlt
fistp val
invoke dwtoa,val,addr buf



buf is =5666
and i separated last 2 characters
result is -56.66 after separated



qWord

Quote from: Force on March 26, 2014, 11:05:38 PMI am trying to make a Ftoa

isn't that  simpliest way for it?
that method works when you know the range of your results. Otherwise you could extract the mantissa digits by converting the value to a n-digit integer as:
mantissa = x * 10-floor(log10(|x|)) * 10n-1   with 1 ≤ n ≤ 18
The actual digits could be get (e.g.) using the FPU instruction FBSTP, which saves a 18 digit BCD-integer. Remarks that this method is not exact due to rounding errors.
include \masm32\include\masm32rt.inc
.686
.const
    value REAL8 -123456.7890123456789E+10
    nm1 REAL10 1.0E17
    inf REAl10 07fff8000000000000000r ; 1.0*2^(emax+1)
.code
main proc
LOCAL exp10:SDWORD
LOCAL bcd:TBYTE
LOCAL sz[32]:CHAR
   
    finit
    fld value
    .repeat
       
        ; test special values
        fldz
        fcomip st,st(1)
        .if PARITY?
            ; value = NaN
            fstp st
            mov DWORD ptr sz,"NaN"
            .break
        .elseif ZERO?
            ; value = +-zero
            fstp st
            mov DWORD ptr sz,"0.0"
            .break
        .endif
        fld inf
        fcomi st,st(1)
        .if ZERO?
            ; value = +Infinite
            fstp st
            fstp st
            mov DWORD ptr sz,"fnI+"
            mov sz[4],0
            .break
        .endif
        fchs
        fcomip st,st(1)
        .if ZERO?
            ; value = -Infinite
            fstp st
            mov DWORD ptr sz,"fnI-"
            mov sz[4],0
            .break
        .endif

        ; log10(|x|)
        fld st
        fabs
        fldlg2
        fxch
        fyl2x
       
        ; floor(log10(|x|))
        fstcw WORD ptr [esp-4]
        mov ax,WORD ptr [esp-4]
        and ax,NOT 0110000000000y
        or ax,0110000000000y
        mov WORD ptr [esp-2],ax
        fldcw WORD ptr [esp-2]
        frndint
        fldcw WORD ptr [esp-4]
        fist exp10
   
        ; -exp10
        fchs
       
        ;/* 10^(-exp10) = 2^(st(0)*ld(10)) */
        fldl2t
        fmulp st(1),st
        fld st(0)
        frndint
        fsub st(1),st(0)
        fxch
        f2xm1
        fld1
        faddp st(1),st
        fscale
        fstp st(1)
       
        ; mantissa = x * 10^(-exp10)
        fmulp st(1),st
       
        ; mantissa -> integer
        fld nm1
        fmulp st(1),st
        ; set BCD integer
        fbstp bcd
       
        ; get sign
        xor edi,edi
        .if BYTE ptr bcd[9] & 80h
            mov sz[edi],'-'
            add edi,1
        .endif
       
        ; get leading digits and place dot
        movzx eax,BYTE ptr bcd[8]
        mov edx,eax
        shr edx,4
        and eax,0fh
        add edx,'0'
        add eax,'0'
        mov sz[edi+0],dl
        mov sz[edi+1],'.'
        mov sz[edi+2],al
        add edi,3
       
        ; get remaining digits
        mov esi,7
        .while SDWORD ptr esi >= 0
            movzx eax,BYTE ptr bcd[esi]
            mov edx,eax
            shr edx,4
            and eax,0fh
            add edx,'0'
            add eax,'0'
            mov sz[edi+0],dl
            mov sz[edi+1],al
            add edi,2
            add esi,-1
        .endw
       
        ; print exponent if needed
        .if exp10
            mov sz[edi],'E'
            add edi,1
            ; ... integer -> string
            fnc crt_sprintf,ADDR sz[edi],"%+d",exp10
        .else
            mov sz[edi],0
        .endif
    .until 1
   
    print ADDR sz,13,10
    fnc crt_printf,"%E\n",value
    inkey
   
   
    exit
main endp
end main
MREAL macros - when you need floating point arithmetic while assembling!

Force

Thanks qWord
sure your code will help me