Search code examples
assemblyfloating-pointfloating-point-conversionx87

x8086 Assembly, pushing 0.0001 onto stack becomes 9.99999.. instead of 0.0001


I am trying to implement newtons algorithm for square roots. I have included the complete C program so you can see what i am trying to do. I am trying to write the C program included below in assembly. Right now i am just trying to correctly write the while loop. I am pushing 0.0001 onto the stack with the command fld accuracy. Below is the screenshot of my registers. ST0 should be 0.0001, but instead it is 9.999. How do i correct this value so that i can do a compare with 0.0001 instead of 9.999..? xcv

.586
.MODEL FLAT
.STACK 4096                 
.data
    PUBLIC _newton
upper REAL4 9.0
accuracy REAL4 0.00001
lower REAL4 1.0
.code

_newton  PROC

        finit   ;initialize fpu
        fld upper
        fld lower
        fsub
        fld accuracy
        fcom
        ;if less than call code for the rest of the algorithm.
        mov eax, 0
        ret

_newton ENDP
END

C version of the algorithm i am implementing:

double sqrtX (double x)
{
    const double ACCURACY=0.00001;
    double lower, upper, guess;
    double number;

    number = x;
    lower = 1;
    upper = number;

    while ((upper-lower) > ACCURACY)
    {
        guess = (lower + upper) / 2;
        if((guess * guess) > number)
        {
            upper = guess;
        }
        else
        {
            lower = guess;
        }
    }
    return (lower + upper)/2;
}

Solution

  • That's 9.99...e-6 which is the closest representable FP value to 0.00001.

    You missed the exponent part of the scientific notation, and that 0.00001 is not exactly representable in binary floating point.