Why is fprem1 instruction not producing the expected results?

133 Views Asked by At

In the book of the art of assembly language, it is said that:

The fprem1 instruction computes a partial remainder. fprem1 computes the partial remainder of st0/st1. If the difference between the exponents of ST0 and ST1 is less than 64, fprem1 can compute the exact remainder in one operation.

ST0 and ST1 are the FPU data registers. so I wanted to test its performance. My code is like this:

program  exercise;

#include( "stdlib.hhf" );
static
          x: real80:=156.5e18;//first number
          y: real80:=14.36;  //second number
          z:real80;  // partial remainder
begin exercise;
     fld(y);    //y goes into st0
     fld(x);    //now x goes into st0 but previous content of st0 
                //(that is st1) will move into st1, so x is into st0 and y is into st1
     fprem1();  //calculates the remainder of st0/st1 (here x/y )but 
                // for getting the remainder, the quotient will round to the nearest value and then
                //  remainder = st0 - rounded quotient*st1==>>that is
                // equivalent by remainder= x-rounded quotient*y 
                //  ===>> then the remainder  can be positive or negative.
     fstp(z);   //this will store the partial remainder in the z real80 variable.
     stdout.put("z:  ",z); 
end  exercise;

But when I run this program, realized that for small power differences, the results It can be expected, but for larger differences, the results are far from expected.

 I have summarized my result below:
      dividing               expected remainder     program remainder
     *****************************************************************      
1)    156.5/14.36                  -1.46          -1.4599..9e000
2)    156.5e1/14.36                -.24           -2.39e-1
3)    156.5e2/14.36                -2.4           -2.39
4)    156.5e3/14.36                 4.72           4.7200...619
5)    156.5e4/14.36                 4.12           4.1200...6195
6)    156.5e5/14.36                -1.88          -1.8799...805
7)    156.5e6/14.36                -4.44          -4.4399..3805
8)    156.5e7/14.36                -1.32          -1.3199...5017
9)    156.5e8/14.36                 1.16           1.16006..826
10)   156.5e9/14.36                -2.76          -2.7599..737
11)   156.5e10/14.36                1.12           1.1200619..627
12)   156.5e11/14.36               -3.16          -3.159380..739
13)   156.5e12/14.36               -2.88          -2.873805..346
14)   156.5e13/14.36               -0.08          -7.99..e-2  ~= -0.079
15)   156.5e14/14.36               -0.8           -7.99..e-1  ~= -0.79
16)   156.5e15/14.36                6.36           6.36340...924
17)   156.5e16/14.36                6.16           6.1940300..120
18)   156.5e17/14.36                4.16           4.500300559
        /***** unacceptable results (from program) at bellow *****/
19)   156.5e18/14.36       (expected) 1.48          5.13274..e10                      
20)   156.5e19/14.36       (expected) 0.44          5.13274..e10 
 
     ****************************************************************   
The Results 19) and 20) is unacceptable, because the remainder can not 
  be greater than divisor, which is incorrect.
>>Am I doing wrong? Or is there a problem with this instruction(fprem1)?
Can someone explain my problem? What can I do? Thanks.

  
0

There are 0 best solutions below