Decimal Calculation rather than Binary


Most calculations on computers are done using binary arithmetic.  The numbers used are often 8 byte in size at the most.  Integer mathematical operations tend to be accurate between 1 to 4,294,967,295.  Outside this range errors can manifest because of the limitations of 8 byte integers.  Some computers are using 16 byte integers, but again this has limitations when numbers bigger than 1,152,921,504,606,846,975 are needed.

Floating point arithmetic runs into problems when calculating fractional numbers.  For some decimal fractions there is no binary equivalent. For example "1001/5 = 200.2".  On my computer using floating point arithmetic I get the answer of 200.19999999999999.  This rounds up to 200.2 to 2 decimal places.  No problem for small issues.  Might be a problem if you are calculating the position of a space probe that is approaching Pluto or determining if an asteroid may be in danger of hitting the Earth at some point in the future.

The calculator in this problem uses decimal mathematical calculations.  This avoids the problems with decimal fractions with no binary equivalent.  The calculations are using decimal (not binary) numbers with 100 or more digits.


Some of the code is shown below.  It is in microsoft c and with some Windows API.

what it does Window code subroutine
converts a number string and converts it into a 100 digit number structure void FAR PASCAL convert100(char *tstring, struct BigNum *BN)
converts a 100 digit number structure back into a number string void FAR PASCAL ConvertBack(char *tstring, struct BigNum *BN1)
Takes two 100 digit number structures (BN1 and BN2) and adds them together and puts result into BNResult BOOL FAR PASCAL Add100(struct BigNum *BN1,
                       struct BigNum *BN2, struct BigNum *BNResult)
Takes two 100 digit number structures (BN1 and BN2) and adds them together and puts result into BNResult.

The calculation not complete because any errors from division have not been multiplied.
BOOL FAR PASCAL Mull100(struct BigNum *BN1,
                       struct BigNum *BN2, struct BigNum *BNResult)
Full multiplication of 2 numbers with result and error Mull100(&BN1, &BN2, &BNResult);
Mull100(&BNTotError, &BN2, &BNTotErrorResult);
CopyMemory(&BNTotError, &BNTotErrorResult,  sizeof(struct BigNum));
Division is complex because it is possible to get a remainder which gets bigger when two numbers are multiplied together and smaller when a number with a remainder is divided by another number.
Divides number N1 by number N2 using dividing and mutiplying methods until the error is smaller than a certain amount int FAR PASCAL DivideNo1byNo2()
checks the error from the division routine BOOL FAR PASCAL Div100Check(HWND hDlg, struct BigNum *BNTop,  struct BigNum *BNDivide,
                              struct BigNum *BNResult,   int ErrorSize)
Full Division routine ConvertBack(No1, &BNFirst);
ConvertBack(No2, &BNSecond);
DivideNo1byNo2();    //    No1 has result
 convert100(No1, &BNResult);


#define BIGCALCMEMSIZE 1000

struct BigNum
{
    BOOL MINUS;
    BOOL ERROR1;
    int Carry;
    int EXP;
    unsigned char Sstring[BIGCALCMEMSIZE
];
    int NoInt;
};


struct Calculate
{
    HWND hDlg;
    HINSTANCE MyInstance;
    char No1[BIGCALCMEMSIZE];
    char No2[2*BIGCALCMEMSIZE];
    char NoERROR[2*BIGCALCMEMSIZE];
    char Temp[2*BIGCALCMEMSIZE];
    RECT rect;
    HANDLE hMem;
    char *lpData;
    struct BigNum BNFirst;
    struct BigNum BNSecond;
    struct BigNum BNResult;
    struct BigNum Z1, Z2, TWO, Yn, Yn1;
    struct BigNum BNtemp1, BNError, BNTotError;
    struct BigNum BNDivideError;
    unsigned char ConvertBackNo2[BIGCALCMEMSIZE];
    char ConvertBackResult[BIGCALCMEMSIZE+2];
    unsigned char No1Add[BIGCALCMEMSIZE+2];
    unsigned char No2Add[BIGCALCMEMSIZE+2];
    struct ListingBox1 CalcList;
    struct ListingBox2 CalcListShort;
    BOOL CANSHIFT;
    BOOL LISTCMD;
    int ErrorSize;
    int decmove, decmoved;
    int button;
    char tstring[500];
    char astring[500];
    char String[2000];
    char hpAddress[3000];
    char hpAddress2[3000];
    int charpos[26];
    char *a, *b, *c, *d;
    struct TypeShort ProfitList[23];
    int EditBox[14];
    char *ffa;
    int fi, fj, fk;
    int i, j, k, input, count, calcpos;
    int br, bl;
    int ar, al;
    int SHADBASE;
    int allow;
    int deci, ei;
    BOOL NUMBER;
    BOOL NONCALC;
    BOOL NOMATHS;
    int days, hrs, min;
    int day, month, year;
    long fltemp;
    double secs;
    __int64 tsize;
    __int64 fsize;
    __int64 fsizeslack;
    div_t div_result;
    double f, fy, fz;
    double no[MAXCALCNO+10];    //    allow for spare needs
    struct BracketStructures Brackets[(2*MAXCALCNO)+10];   
    //    MAXCALCNO max numbers + MAXCALCNO operatators = 100 A+A+A+A+A can be A+(AxA)+(AxA) max 2 brackets 5 items
    //   
    double *fa, *fb;
    int LoWord;
    BOOL FIRSTTIME;
    BOOL DECPOINT;
    BOOL DCHAR;
    BOOL TIME;
    BOOL REMOVESTRUCT;
    BOOL STAR;
    DWORD cursor;
    WORD position;
    WORD position1;
};

void FAR PASCAL convert100(char *tstring, struct BigNum *BN)
{
    unsigned char *p, *pdec, *d, ch;
    int i;
    ZeroMemory(BN, sizeof(struct BigNum));
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE);

    //    we need to protect tstring from possible mangling
    strcpy(Calc->Temp, tstring);
   
    //    1.817462e-027
   
    p = (unsigned char *) tstring;
    if (*p == '-')
    {
        BN->MINUS = TRUE;
        p++;
    }
    pdec = 0;
   
    while (*p)
    {
        if (*p == 46)    //    dec point
        {
            pdec = p;
        }
       
        if (*p == 'e')
        {
            *p = '\0';
            p++;
            BN->EXP = atoi((char *) p);
            break;
            //    put in BN using e info
        }
        p++;
    }


    if ((BN->EXP & 1) != 0)
    {
        //    this is odd
        //    we need to make even
        if (!pdec)
        {
            //    we need to add 0
            p = (unsigned char *) tstring;
            while (*p)
            {
                p++;
            }
            *p = '0';
            p++;
            *p = '\0';
        }
        else
        {
            //    we need to move decimal point to right
            p = pdec;
            char b;
            b = *(p+1);
            *(p+1) = 46;
            *p = b;
            pdec++;
        }
        BN->EXP--;    //    10.12 to 101.2 e1 to e0
    }

    i = strlen(tstring);
    d = (unsigned char *) Calc->ConvertBackResult;
    if (pdec)
    {
        *pdec = '\0';
        p = (unsigned char *) tstring;
        if (*p == '-')
        {
            p++;
        }
        int j = strlen((char *)p);
        if ((j & 1) != 0)   /* if odd number of digits, append a '0' to make it even */
        {
            //    we want to get first byte
            *d = '0';
            d++;
            while (*p)
            {
                *d = *p;
                d++;
                p++;
            }
        }
        else
        {
            while (*p)
            {
                *d = *p;
                d++;
                p++;
            }
        }

        if (i > j+1)
        {
            //    we have decimal characters
            p = pdec+1;
            j = strlen((char *) p);
            *d = '.';
            d++;
            while (*p)
            {
                *d = *p;
                d++;
                p++;
            }
            if ((j & 1) != 0)   /* if odd number of digits, append a '0' to make it even */
            {
                //    we want to get last byte
                *d = '0';
                d++;
            }
            *d = '\0';
        }

    }
    else
    {
        p = (unsigned char *) tstring;
        if (*p == '-')
        {
            p++;
        }
        int j = strlen((char *) p);
        if ((j & 1) != 0)   /* if odd number of digits, append a '0' to make it even */
        {
            //    we want to get first byte
            *d = '0';
            d++;
        }
        while (*p)
        {
            *d = *p;
            d++;
            p++;
        }
        *d = '\0';
    }

    //    now to convert into hundreds
    p = (unsigned char *) Calc->ConvertBackResult;
    d = BN->Sstring;
    BN->NoInt = 0;
    pdec = 0;
    while (*p)
    {
        if (*p == 46)
        {
            pdec = p;
            *d = 200;
            d++;
            p++;
            BN->NoInt++;
        }
        BN->NoInt++;
        ch = *p++ - '0';
        ch = (10 * ch + *p++ - '0');
        *d = ch;
        d++;
    }
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE);
    //    we need to clear out 0 at end of string if decimal point present
    if (pdec)
    {
        p = BN->Sstring+BN->NoInt-1;    //    this includes contents
        while (p != BN->Sstring)
        {
            if (*p != 0)
            {
                break;
            }
            p--;
            BN->NoInt--;
        }
    }
    if (BN->NoInt)
    {
        p = BN->Sstring;
        while (*p == 0 && BN->NoInt)
        {
            p++;
            BN->NoInt--;
        }
    }
    if (BN->NoInt == 0)
    {
        ZeroMemory(BN, sizeof(struct BigNum));
        return;
    }
   
    if (p != BN->Sstring)
    {
        CopyMemory(BN->Sstring, p, BN->NoInt);
        ZeroMemory(BN->Sstring+BN->NoInt, BIGCALCMEMSIZE- BN->NoInt);
    }
   
    //    we have BN->EXP
    ShiftBigNumber(BN);
    // tstring has been preserved intact
    strcpy(tstring, Calc->Temp);
}

int FAR PASCAL ShiftBigNumber(struct BigNum *BN)
{
    Calc->CANSHIFT = FALSE;
    //    BN->EXP == 0 leave
    if ((BN->EXP & 1) != 0)
    {
        //    this is odd so cannot shift
        return BN->EXP;
    }

    if (BN->EXP == 0)
    {
        //    no shift
        return BN->EXP;
    }

   
    if (BN->EXP < 1)
    {
        if (BN->NoInt - BN->EXP < BIGCALCMEMSIZE)
        {
            //    can shift right
            Calc->CANSHIFT = TRUE;
        }
        //    shift right
        //    find decimal point
    }
    if (BN->EXP > 1)
    {
        //    shift left
        if (BN->NoInt + BN->EXP < BIGCALCMEMSIZE)
        {
            //    can shift left
            Calc->CANSHIFT = TRUE;
        }
    }

    if (!Calc->CANSHIFT)
    {
        return BN->EXP;
    }

    //    Calc->CANSHIFT true   
       
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE);
    unsigned char *p, *pdec, *m, *end;
    p = BN->Sstring;
    pdec = 0;
    end = (unsigned char *) BN->Sstring+BN->NoInt;
    while (p != end)
    {
        if (*p == 200)
        {
            pdec = p;
            break;
        }
        p++;
    }
    if (!pdec)
    {
        *p = 200;
        pdec = p;
        BN->NoInt++;
    }
    // find decimal point
    //    we can go two ways right or left
    int i;
    BN->EXP /= 2;
    if (BN->EXP < 0)
    {
        BN->EXP *= -1;
        //    we must move dec point to left
        CopyMemory(Calc->ConvertBackResult+BIGCALCMEMSIZE-BN->NoInt,
            BN->Sstring, BN->NoInt);
        pdec = (unsigned char *) Calc->ConvertBackResult+BIGCALCMEMSIZE-BN->NoInt + (pdec - BN->Sstring);
        end =  (unsigned char *) BN->Sstring;
        p = pdec;
        while (p != end && BN->EXP > 0)
        {
            //    we exchange dec point and move left
            *p = *(p-1);
            *(p-1) = 200;
            BN->EXP--;
            pdec--;
            p--;
        }
        i = 0-BN->EXP;
    }
    if (BN->EXP > 0)
    {
        //    we must move dec point to right
        CopyMemory(Calc->ConvertBackResult, BN->Sstring, BN->NoInt);
        pdec = (unsigned char *) Calc->ConvertBackResult+(pdec - BN->Sstring);
        end =  (unsigned char *) Calc->ConvertBackResult+BIGCALCMEMSIZE;
        p = pdec;
        while (p != end && BN->EXP > 0)
        {
            //    we exchange dec point and move right
            *p = *(p+1);
            *(p+1) = 200;
            BN->EXP--;
            pdec++;
            p++;
        }
        i = BN->EXP;
    }
    p = (unsigned char *) Calc->ConvertBackResult;
    while (*p == 0)
    {
        p++;
    }
    m = (unsigned char *) Calc->ConvertBackResult+BIGCALCMEMSIZE;
    while (*m == 0)
    {
        m--;
    }
    BOOL MINUS = BN->MINUS;
    ZeroMemory(BN, sizeof(struct BigNum));
    BN->NoInt = m-p+1;    //    this ensures that last figure included
    CopyMemory(BN->Sstring, p, BN->NoInt);
    BN->MINUS = MINUS;
    BN->EXP = i;
   
    return BN->EXP;
}

void FAR PASCAL ConvertBack(char *tstring, struct BigNum *BN1)
{
    unsigned char *b, *c;
    char *a, *d;
    int ch;
    ZeroMemory(Calc->ConvertBackNo2, BIGCALCMEMSIZE);
    a = Calc->ConvertBackResult;
    b = BN1->Sstring;
    c = BN1->Sstring + BN1->NoInt;
   

    while (b < c)
    {
        if (*b == 200)
        {
            //    this is decimal point
            *a = '.';
            a++;
            b++;
        }
        ch = *b;
        //    each ch has two chars
        *(a) = (ch/10) + '0';
        a++;
        *a = (ch % 10) + '0';
        a++;       
        b++;
    }
    *a = '\0';
    a = Calc->ConvertBackResult;
    while (*a == '0' && a != Calc->ConvertBackResult+BIGCALCMEMSIZE)
    {
        a++;
    }

    d = Calc->ConvertBackResult+BIGCALCMEMSIZE;
    while (*d == '0')
    {
        *d = '\0';
        d--;
    }

    d = tstring;
    if (BN1->MINUS)
    {
        *d = '-';
        d++;
    }

    strcpy(d, a);

   
    //    we could have *d = '\0' needs 0 instead
    if (*d == 0)
    {
        *d = '0';
        *(d+1) = '\0';
        return;
    }
    //    we now have number with string of zeros which need trimming
    ZeroMemory(Calc->ConvertBackNo2, BIGCALCMEMSIZE); // 1000
    Calc->DECPOINT = FALSE;

    //    we need to check that this has a decimal point
    d = tstring;
    while (*d)
    {
        if (*d == '.')
        {
            Calc->DECPOINT = TRUE;
            break;
        }
        d++;
    }
    if (!Calc->DECPOINT)
    {
        //    do nothing with number as integer not float
       
        return;
    }

    //have decimal number have we got zeros at end
    a = d;
    while (*a)
    {
        a++;
    }
    //    we are end of string
    a--;
    while (*a == '0')
    {
        *a = '\0';
        a--;
    }
    if (*a == '.' && *(a+1) == 0)
    {
        *a = '\0';
    }
    //    should have string with no trailing zeros after dec point
    //    should have plain number if no decimal places
   
}


BOOL FAR PASCAL Add100(struct BigNum *BN1,
                       struct BigNum *BN2, struct BigNum *BNResult)
{
    //    this adds to large numbers together

    if (BN2->NoInt == 0)
    {
        //    we are adding zero
        CopyMemory(BNResult, BN1, sizeof(struct BigNum));
        return TRUE;
    }

    ZeroMemory(BNResult, sizeof(struct BigNum));
    if (BN1->MINUS && BN2->MINUS)
    {
        BNResult->MINUS = TRUE;
    }

    if (BN1->MINUS && !BN2->MINUS)
    {
        BN1->MINUS = FALSE;
        Sub100(BN2, BN1, BNResult);
        BN1->MINUS = TRUE;
        return TRUE;
    }

    if (BN2->MINUS && !BN1->MINUS)
    {
        BN2->MINUS = FALSE;
        Sub100(BN1, BN2, BNResult);
        BN2->MINUS = TRUE;
        return TRUE;
    }

    //    we have to add two strings together
    //    we have to center on the decimal point
    int Stop;
    Calc->i = LineUp100(BN1, BN2, &Stop);
   
    if (Calc->i == -1)
    {
        //    marker to say we cannot lineup
        return FALSE;
    }
    //    we have line up
   
    unsigned char ch, *a, *b, *c, *stop, *pdec;
    int carry;
    pdec = 0;
    a = &Calc->No1Add[BIGCALCMEMSIZE];
    b = &Calc->No2Add[BIGCALCMEMSIZE];
    //    we have to make allowance for carry
    if (Stop > 2)
    {
        Stop -=2;
    }
    stop = Calc->No1Add+Stop;
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE);
    c = (unsigned char *) &Calc->ConvertBackResult[BIGCALCMEMSIZE];
    carry = 0;
    while (a > (stop))
    {
        if (*a == 200)
        {
            pdec = c;
            *c = 200;    //    dec point
            c--;
           
            if (*b != 200 && b != 0)
            {
                ErrBox("dec point problem");
            }
            b--;
            a--;
        }
       
        ch = *a + *b + carry;
        if (ch >= 100)
        {
            *c = ch -100;
            carry = 1;
        }
        else
        {
            *c = ch;
            carry = 0;
        }
        a--;
        b--;
        c--;
    }
    //    now want result
    if (carry == 1)
    {
        *c = 1;
    }
    //    remove any leading zeros
    a = (unsigned char *) Calc->ConvertBackResult+Stop; //
    while (*a == 0)
    {
        if (a > (unsigned char *) &Calc->ConvertBackResult[BIGCALCMEMSIZE])
        {
            break;
        }
        a++;
    }
    //    remove any trailing zeros after the decimal point
    if (pdec)
    {
        b = (unsigned char *) &Calc->ConvertBackResult[BIGCALCMEMSIZE];
        while (*b == 0 && b > pdec)
        {
            b--;
        }
    }
  
    BNResult->NoInt = b-a+1; //    a & b contain data
    CopyMemory(BNResult->Sstring, a, BNResult->NoInt);
    return TRUE;

}


BOOL FAR PASCAL Sub100(struct BigNum *PLUS,
                       struct BigNum *MINUS, struct BigNum *BNResult)
{
  
    if (MINUS->NoInt == 0)
    {
        //    we are subtracting zero
        CopyMemory(BNResult, PLUS, sizeof(struct BigNum));
        return TRUE;;
    }
  
    if (MINUS->MINUS)
    {
        MINUS->MINUS = FALSE;
        if (!PLUS->MINUS)
        {
            Add100(PLUS, MINUS, BNResult);
        }
        else
        {
            Sub100(PLUS, MINUS, BNResult);
        }
        MINUS->MINUS = TRUE;
        return TRUE;
    }
    //    !MINUS->MINUS
  
    if (PLUS->MINUS)
    {
        PLUS->MINUS = FALSE;
        Add100(PLUS, MINUS, BNResult);
        PLUS->MINUS = TRUE;
        return TRUE;
    }

    //    we now need to determine which is bigger
    int Stop;
    Calc->i = LineUp100(PLUS, MINUS, &Stop);
    if (Calc->i == -1)
    {
        //    marker to say we cannot lineup
        return FALSE;
    }
    BOOL BIG, SAME;
    unsigned char *pdec, *a, *b, *stop, *c;
    int carry, ch;
    pdec = 0;
    //    make sure we are at start
    if (Stop > 2)
    {
        Stop -=2;
    }
    stop = Calc->No1Add+Stop;
    a = (unsigned char *) Calc->No1Add+Stop;
    b = (unsigned char *) &Calc->No2Add+Stop;
  
    stop = (unsigned char *) Calc->No1Add+BIGCALCMEMSIZE;
    SAME = TRUE;
    BIG = FALSE;
    while (a < stop+1)
    {
        if (*a < *b)
        {
            SAME = FALSE;
            BIG = TRUE;
            break;
        }
        if (*a != *b)
        {
            SAME = FALSE;
            break;
        }
        a++;
        b++;
    }
    ZeroMemory(BNResult, sizeof(struct BigNum));
    //    now we subtract MINUS from PLUS
    //    if (PLUS < MINUS) we get minus result
    //    if (PLUS = Minus we get zero
    //    if (PLUS > MINUS) we get positive
    if (SAME)
    {
        //    we get zero result
        BNResult->NoInt = 0;
        return TRUE;
    }
    if (BIG)
    {
        BNResult->MINUS = TRUE;
        b = Calc->No1Add+BIGCALCMEMSIZE;
        a = Calc->No2Add+BIGCALCMEMSIZE;
        //    we reverse a & b
    }
    else
    {
        a = Calc->No1Add+BIGCALCMEMSIZE;
        b = Calc->No2Add+BIGCALCMEMSIZE;
    }
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE);
    c = (unsigned char *) Calc->ConvertBackResult+BIGCALCMEMSIZE;
    stop = a-BIGCALCMEMSIZE+Stop;
    carry = 0;
    while (a > (stop-1))
    {
        if (*a == 200)
        {
            *c = 200;
            pdec = c;
            a--;
            b--;
            c--;
        }

        ch = 100 + *a - *b - carry;
        if (ch >= 100)
        {
            *c = ch -100;
            carry = 0;
        }
        else
        {
            *c = ch;
            carry = 1;
        }
        a--;
        b--;
        c--;
    }
    //    remove leading zeros
    a = (unsigned char *) Calc->ConvertBackResult+Stop;
    while (*a == 0 && a < (unsigned char *) &Calc->ConvertBackResult[BIGCALCMEMSIZE])
    {
        a++;
    }
  
    //    remove trailing zeros after decimal point
    b = (unsigned char *) &Calc->ConvertBackResult[BIGCALCMEMSIZE];
    while (*b == 0 && b > pdec)
    {
        b--;
    }

    BNResult->NoInt = b-a+1; //    a & b contain data
    CopyMemory(BNResult->Sstring, a, BNResult->NoInt);
    return TRUE;
}


int FAR PASCAL mullmull100(int No, unsigned char *tstring,
            unsigned char *result, unsigned char *tstringend)
{
    unsigned char *a, *b, *pdec;
    int ch, carry, temp;
    a = result;
    b = tstringend;
    carry = 0;
    pdec = tstringend;

    while (b > tstring-1)
    {
        temp = *b;
        if (*a == 200)
        {
            a--;
        }

        if (*b == 200)
        {
            pdec = b;
            b--;
            temp = *b;
        }

        ch = (temp * No) + carry + (int) *a;
        if (ch >= 100)
        {
            carry = ch/100;
            *a = ch % 100;
        }
        else
        {
            *a = ch;
            carry = 0;
        }
        a--;
        b--;
    }
    //    carry could be substantial
    while (carry > 0)
    {
        if (*a == 200)
        {
            a--;
        }
        ch = carry + *a;
        if (ch >= 100)
        {
            carry = ch/100;
            *a = ch % 100;
        }
        else
        {
            *a = ch;
            carry = 0;
        }
        a--;
    }
    ch = tstringend- pdec;
    return ch;
}


int FAR PASCAL DivideNo1byNo2()
{
        //    6/2
        //    we have to worry about minus problem
        //    -noxno1 fail -nox-no1 fail nox-no1 fail

    BOOL MINUS1 = FALSE;
    BOOL MINUS2 = FALSE;
    BOOL ERRORMINUS = FALSE;
    char *a;

   
    //    we need to remove trailing zeros if have dec point
    a = Calc->No2;
    while (*a)
    {
        if (*a == '.')
        {
            while (*a)
            {
                a++;
            }
            //    we are end of string
            a--;
            while (*a == '0')
            {
                *a = '\0';
                a--;
            }
            if (*a == '.' && *(a+1) == 0)
            {
                *a = '\0';
            }
            break;
        }
        a++;
    }
    //    should have string with no trailing zeros after dec point
    //    should have plain number if no decimal places
       
    // we need to check if we have a zero Calc->No2
    if (Calc->No2[0] == 0 ||
        (Calc->No2[0] == '0' && Calc->No2[1] == 0))
    {
        return -1;
    }


    //    Calc->ErrorSize int
    ConvertBack(Calc->NoERROR, &Calc->BNTotError);
    if (Calc->NoERROR[0] == '-')
    {
        ERRORMINUS = TRUE;
        convert100(&Calc->NoERROR[1], &Calc->BNTotError);
    }
   
    a = Calc->No1;

    //Calc->a = Calc->No1;
    if (Calc->No1[0] == '-')
    {
        MINUS1 = TRUE;
        //    Calc->No1 has been modified by convert100
        //convert100(&Calc->No1[1], &Calc->BNFirst);
        a = &Calc->No1[1];
    }
    convert100(a, &Calc->BNFirst);

    a = Calc->No2;
    if (Calc->No2[0] == '-')
    {
        MINUS2 = TRUE;
        //    Calc->No1 has been modified by convert100
        //convert100(&Calc->No2[1], &Calc->BNSecond);
        a = &Calc->No2[1];
    }
    convert100(a, &Calc->BNSecond);



    //    Calc->No1
    //    Calc->No2
//    ConvertBack(Calc->Temp, &Calc->BNTotError);


    if (!Div100Check(0, &Calc->BNTotError,
        &Calc->BNSecond,
        &Calc->BNResult,
        Calc->ErrorSize))
    {
//            DIVIDEBYZERO = TRUE;
        return -1;
    }

    if (!Div100Check(0, &Calc->BNFirst,
        &Calc->BNSecond,
        &Calc->BNResult,
        Calc->ErrorSize))
    {
//            DIVIDEBYZERO = TRUE;
        return -1;
    }
    Add100(&Calc->BNDivideError, &Calc->BNTotError, &Calc->BNFirst);
    CopyMemory(&Calc->BNTotError, &Calc->BNFirst,
        sizeof(struct BigNum));

    //    we have calculation with everything positive
    //    we now have to get signs right
    //    -err/-no1 = +, err/-no1 = -, -err/no1 = -
   
    if ((MINUS1 && !MINUS2) ||
        (!MINUS1 && MINUS2))
    {
        //    we have -result
        a = &Calc->No1[1];
        Calc->No1[0] = '-';
        MINUS1 = TRUE;
    }
    else
    {
        //    we have +result
        a = Calc->No1;
        MINUS1 = FALSE;
    }
    ConvertBack(a, &Calc->BNResult);
    //    we could have a zero value
   
    //convert100(Calc->No1, &Calc->BNResult);
    return 1;
}


BOOL FAR PASCAL Div100Check(HWND hDlg, struct BigNum *BNTop,
                            struct BigNum *BNDivide,
                              struct BigNum *BNResult,
                           int ErrorSize)
{
    //char No2[DCALCMEMSIZE];
    int i;
//    unsigned char xYn[100];
    double test1;    //    this will handle upto 50 chars
    ZeroMemory(&Calc->BNtemp1, sizeof(struct BigNum));
    ZeroMemory(&Calc->Yn, sizeof(struct BigNum));
    ZeroMemory(&Calc->Z2, sizeof(struct BigNum));
    ZeroMemory(&Calc->Z1, sizeof(struct BigNum));
    ZeroMemory(&Calc->TWO, sizeof(struct BigNum));
    ZeroMemory(&Calc->Yn1, sizeof(struct BigNum));
    ZeroMemory(Calc->ConvertBackResult, BIGCALCMEMSIZE+1);
    ZeroMemory(Calc->No1Add, BIGCALCMEMSIZE);
    ZeroMemory(Calc->No2Add, BIGCALCMEMSIZE);
   
    if (ErrorSize & 1)
    if ((ErrorSize & 1) != 0)
    {
        //    this is odd
        //    we need to make even
        ErrorSize++;
    }

    sprintf((char *) Calc->No2Add, "1.0e-%d", ErrorSize);
    //    convert100 preserves string by copying to temp and then
    //    copying temp back to string
    char TWO[3];
    TWO[0] = '2';
    TWO[1] = '\0';

    convert100(TWO, &Calc->TWO);

    convert100((char *) Calc->No2Add,
        &Calc->BNDivideError);
   
    ConvertBack((char *) Calc->No2Add, BNDivide);
    //    we have to check for zero
    if (Calc->No2Add[0] == 0)
    {
        ErrBox("Divide by Zero Error");
        return FALSE;
    }


    test1 = 1/atof((char *) Calc->No2Add);
    sprintf(Calc->No2, "%.30e", test1);
    convert100(Calc->No2, &Calc->Yn);
    BOOL GoodEnough = FALSE;
    while (!GoodEnough)
    {
        //    BNDivide is approx
       
        Mull100(BNDivide, &Calc->Yn, &Calc->Z2);    //    XYn = Z2 approx 1 - 2x2

        Sub100(&Calc->TWO, &Calc->Z2, &Calc->Z1);    //    2-XYn = Z1
        Mull100(&Calc->Z1, &Calc->Yn, &Calc->Yn1);    //    Yn+1 = Yn(2-XYn)
        CopyMemory(&Calc->Yn, &Calc->Yn1, sizeof(struct BigNum));
        //    start again
        Mull100(BNTop, &Calc->Yn, BNResult);    //    div result
        //    now do error
        Mull100(BNDivide, BNResult, &Calc->BNtemp1);    //    div x result should be top
        Sub100(BNTop, &Calc->BNtemp1, &Calc->BNError);    //    error in result
        Calc->BNError.MINUS = 0;    //    we want positive error
       
        i = Equal100(&Calc->BNDivideError,  &Calc->BNError);
        if (i == 0 || i == 1)
        {
        //    result is accurate enough
            GoodEnough = TRUE;
        }
        //    go round again
    }

    //    we could have 8.32 / 4.16 = 2
    //    get 1.999999999999999999999999999999999999999999999999999999999999
    //    +    0.000000000000000000000000000000000000000000000000000000000000
    //        2.
//    ConvertBack(Calc->No1, BNResult);
    Add100(BNResult, &Calc->BNDivideError, &Calc->Z2);
    unsigned char *a, *pdec;
    int k;
    a = Calc->Z2.Sstring;
    pdec = 0;
    while (a < Calc->Z2.Sstring+BIGCALCMEMSIZE)
    {
        if (*a == 200)
        {
            pdec = a;
            break;
        }
        a++;
    }
    if (pdec)
    {
        //    found decimal point
        a = pdec+Calc->BNDivideError.NoInt-1;    //    dec point++ 25 points next item
        Calc->Z2.NoInt = a - Calc->Z2.Sstring;    //    include contents
        k = Calc->Z2.NoInt;
        while (a != pdec)
        {
            if (*a == 0)
            {
                Calc->Z2.NoInt--;
            }
            else
            {
                break;
            }
            a--;
        }
    }

    if (Calc->Z2.NoInt < k)
    {
        //    we have change in number of sig figs
        CopyMemory(BNResult, &Calc->Z2, sizeof(struct BigNum));
        Calc->BNDivideError.Sstring[k] = 2;
    }
   
    //    we need to zero every thing beyond k
    ZeroMemory(&BNResult->Sstring[k], BIGCALCMEMSIZE-k);
        BNResult->NoInt = k;
   
   
    ZeroMemory(&Calc->Yn, sizeof(struct BigNum));
    ZeroMemory(&Calc->Z2, sizeof(struct BigNum));
    ZeroMemory(&Calc->Z1, sizeof(struct BigNum));
    ZeroMemory(&Calc->TWO, sizeof(struct BigNum));
    ZeroMemory(&Calc->Yn1, sizeof(struct BigNum));
    //ZeroMemory(&Calc->BNDivideError, sizeof(struct BigNum));
    //    needed in list calculations
    ZeroMemory(&Calc->BNError, sizeof(struct BigNum));
    return TRUE;
}