News:

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

FPU compare real to integer problem

Started by RuiLoureiro, March 17, 2012, 01:36:34 PM

Previous topic - Next topic

RuiLoureiro

raymond,

Quote
The only conclusion I can reach from the above quotes is that
"formula 1" uses the absolute value of X

        1. Why do you say "uses the absolute value of X" ?
       
        2. Could you give me an example where X is a negative real10 number
           and Y is not integer and X^Y is a real10 number ?

        3. What about FpuSin question ?

qWord

Quote from: RuiLoureiro on March 18, 2012, 09:59:18 PM        2. Could you give me an example where X is a negative real10 number
           and Y is not integer and X^Y is a real10 number ?
e.g.: x1/n  ; n = +-1, +-3, +-5,... ; x can be any positive or negativ value
FPU in a trice: SmplMath
It's that simple!

clive

Quote from: RuiLoureiro
        Could you tell me why it gives Sin( pi ) = -0.00000... ?
        (But FpuCos doesnt give it with pi/2)

        And why not 0.00000... ?

Unusually large, imprecise, value for PI?

22/7 springs to mind, but you should check the FPU constant for PI against your own.
It could be a random act of randomness. Those happen a lot as well.

raymond

Quote1. Why do you say "uses the absolute value of X" ?

Because the usual manner to raise a value X to a power Y when Y is not an integer is to compute the logarithm of X (in whichever base you want), multiply it by the power, and then get the antilog (in the same base) of the product. BUT, logarithms of negative numbers do not exist except with complex numbers (and you don't use them).

Quote2. Could you give me an example where X is a negative real10 number and Y is not integer and X^Y is a real10 number ?

Not without using complex numbers. But, you could express both cartesian (or polar) coordinates of the result with REAL10 numbers. Only the powers of positive numbers can be expresed with a single REAL10 result (the coefficient of the imaginary component would always be 0 when computed as complex numbers).

Quote       Could you tell me why it gives Sin( pi ) = -0.00000... ?
       (But FpuCos doesnt give it with pi/2)

       And why not 0.00000... ?

Regardless of how you assign the value of pi, it will always have some small error (either + or -). If the result of your computation with that pi value is so close to zero that it cannot be returned with the smallest value available according to the precision control of the FPU, it will be returned with +0 or -0 according to which side of the zero the result is closest (the FPU is designed to perform computations with a few extra bits over and above those you see in a REAL10).

BUT, not to worry, if you compare a -0 with a +0 with the FPU, they will be considered as EQUAL.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

raymond

QuoteY is not integer and X^Y is a real10 number ?

Obviously, as the REAL10 exponent get closer and closer to an integer, the result will ressemble more and more the exponentiation by an integer. Here are a few examples to show how close it may become. You can draw your own conclusions.

  X     Y                  r                   i
-3.0  2.10         9.553465958876771   3.104109257329652
-3.0  2.01         9.094930212851599   0.285819696514787
-3.0  2.001        9.009848481854879   0.028305366921538
-3.0  2.0001       9.000988361193504   0.002827743984086
-3.0  2.00001      9.000098871207738   0.000282746445047
-3.0  2.0000000001 9.000000000988751   0.000000002827433
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

RuiLoureiro

#50
Hi all
        I started writing something to solve a real expression a week ago.
        What i want ? The answer is: i dont know exactly.
        What to do ? The answer is: i dont know exactly.
        What is the project ? The answer is: i dont know exactly.
        Is it to solve all kind of expressions ? Probably not.
        Is it to do the same thing as we know ? Probably not.
        What is necessary ? I know: start it.

        I decided to work with fpu and real10 numbers. Is it necessary to
        work with complex numbers ? The answer is: i dont know exactly.
        But i know one thing: i dont want to use it for now.
       
        I have some experience with fpu, but not much. Well, i am going
        to face some problems i know, but we learn with problems to solve.
       
        So, i am in the stage where i go to define what and how to do.

qWord,
        Yes, that is some particular cases to solve. Those and this

                                (X)^(m/n)           m,n integer32

                            SQR(X)=sqr(X)=(X)^(1/2)
                           
        I am thinking to use one particular function to solve it.

        That problem of Yi=Trunc(Y) is solved with a factor
        The error Yi-Y is <1.0e-10 or less

        I use this. After fcomip i remove source. Is this the best
        place to remove it ?

                ; ---------------------------
                ; Move ErrorDelta to be st(1)
                ; ---------------------------
                mov     eax, offset ErrorDelta
                fld     tbyte ptr [eax]
   
                mov     eax, offset ExponentI
                fild    dword ptr [eax]
                mov     eax, offset ExponentZ
                fld     tbyte ptr [eax]
                fsub
               
                fabs
                ; -------
                ; Compare
                ; -------
                fcomip  st(0), st(1)
                fstp    st                        ; ««««« remove source

                fwait
                jpe     short error               
                jb      short _menor
                ja      short _maior
                ;je      short _igual               
    ;_igual:     
   
    _menor:
   
    _maior:
                               
        Thanks

RuiLoureiro

Clive and raymond,

        This is the procedure.               
               
    _sin:       fldpi
                fadd  st,st             ;->2pi
                fxch
               
    @@:         fprem                   ; reduce the angle
                fsin
                fstsw ax
                fwait
                shr   al,1              ; invalid operation ?
                jc    _erro               
                sahf                    ;transfer to the CPU flags
                jpe   @B                ;reduce angle again if necessary
                fstp  st(1)             ;get rid of the 2pi
                jmp   _exit
                ...
               
    _exit:      mov     eax, offset Z
                fstp    tbyte ptr[eax]

        When we write sin(pi) the constant for PI
        is loaded from fpu (fldpi) and stored at a varible X

                fldpi
                mov     eax, offset X
                fstp    tbyte ptr[eax]

        Before we go to _sin, we load it from X

        Thanks  :wink

RuiLoureiro

raymond,
Quote
        Because the usual manner to raise a value X to a power Y when Y is not an integer
is to compute the logarithm of X ...

        Yes, it is what i know

Quote
BUT, logarithms of negative numbers do not exist except with complex numbers

        Yes, it is what i know
        And it tell us that we have other problems if X<0.
       
        If X=0 we use the same procedure and fpu report error and than exit ...

Quote
You can draw your own conclusions.

        I say the same you said: «as the REAL10 exponent get closer and closer
        to an integer, the result will ressemble more and more the exponentiation
        by an integer». So, make all sense to use the integer part of Y and
        give a real10 result. It seems to me.

        Thanks raymond    :wink     

raymond

Just to save you some precious time with unnecessary typing, assuming you are using MASM, you don't have to dereference variables to load the FPU if their size have already been declared in either global or local memory. For example,

                mov     eax, offset ExponentI
                fild    dword ptr [eax]
                mov     eax, offset ExponentZ
                fld     tbyte ptr [eax]
                fsub


If ExponentZ was declared as a tbyte and ExponentI was declared as a dword, you could simply do:

   fild ExponentI
   fld ExponentZ
   fsub


Even shorter:

   fld ExponentZ
   fisubr ExponentI


And it is a waste of your precious time to store the value of pi in memory. It is always available directly from the FPU whenever needed.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

RuiLoureiro

raymond,
        Thank you for your reply
       
Quote
And it is a waste of your precious time to store the value of pi in memory.
It is always available directly from the FPU whenever needed.

        It seems i need to store it to OperandZ. When we type an expression
        it is saved in a string, and it can be "sin (2*pi*20/60)" or
        "sin(pi)" or "sin(5.1*pi*20/70+...)". When we find "(" and ")"
        a procedure should solve it and put the result in OperandZ. Then
        a general procedure solves the function sin(OperandZ). I have
        not a particular procedure to solve "sin(pi)" or other argument.

raymond

QuoteUsing the absolute value of X returns the length of the vector (without the angle) in the complex plane when X is negative.

For those interested in the subject, the angle in the complex plane for X^Y can easily be computed as follows when X is negative and Y is not an integer.
(In the complex plane, the angle is measured against the positive real axis and increases counterclockwise.)

- Compute the vector X^Y with the absolute value of X
- Get the nearest even integer N less than Y
- Subtract it from Y
- The angle in radians = pi*(Y-N), and in degrees = 180*(Y-N)

For example, if Y = 3.12, the nearest even integer (less than Y) is 2
3.12 - 2 = 1.12
the angle = 1.12*pi = 3.5185837720 radians = 201.6 degrees

If Y = -3.12, the nearest even integer (less than Y) is -4
-3.12 - (-4) = 0.88
the angle = 0.88*pi = 2.7646015352 radians = 158.4 degrees
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

RuiLoureiro

Hi all

        This is the Calcula20.
        Try to solve some expressions and say something
        Did you find an error result ?
        Please, tell me to help me

        Thanks  :U


raymond

I notice you return ERROR for X^Y when X is negative and Y is not an integer. :U :wink

I had a quick try with a relatively long expression (using *, /, -, sind, cosd, exp, sqr and a few pi) and it worked OK for it. :clap:
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

dedndave

-------------------------------------------------------------------
Type an expression and press enter [ ex: -pi + 3.1*(7 - 2*8.3) ]
-3^2.5
This is your expression: -3^2.5
This is your Result:  -15.5884572681
-3^2.5=-15.5884572681
---------------------------------------------
Type an expression and press enter [ ex: -pi + 3.1*(7 - 2*8.3) ]


also, how do you exit ? - i didn't see it   :bg

very cool program   :U