● fixed X

除算

除算は fixed_div で行います。
例1.FIXEDVAL値を数値文字列に変換

#include <string.h>
#include "fixedX.h"

#define BIT             128
#define SIZE            (BIT / 8)

/* FIXEDVAL値を 10進数の文字列に変換する */
char        *ntoa(PFIXEDVAL pval,char *pdest)
{
    static FIXEDVAL         ten[SIZE] = {10};
    FIXEDVAL                rem[SIZE];
    char                    *pdestorg = pdest;

    while(fixed_nzero(pval,SIZE)){
        fixed_div(pval,ten,rem,SIZE);
        *pdest++ = (char )(rem[0] + '0');
    }
    *pdest = 0;
    return strrev(pdestorg); /* この方法では前後が逆になるので反転する */
}

#include <stdio.h>

void        main(void )
{
    FIXEDVAL        a[SIZE];
    char            buf[64];

    fixed_atoui(a,SIZE,"21474836475");

    printf("%s\n",ntoa(a,buf));
}
除算は、被除数の格納されていた領域に商を上書きで格納し、指定した別の領域に剰余を格納します。
    fixed_div(a,b,c,width );   →   c = a % b, a /= b
商と剰余を一度に求めるという点では、標準ライブラリの関数div 、ldiv に似ています。

剰余を格納する領域は関数内部の処理にも使用されるため、計算に商しか使用しない場合でも、必ず剰余用の FIXEDVAL領域を指定しなければなりません(ゼロクリアしておく必要はありません)。

なお、それぞれの引数には、同じ領域を指定する事はできません。


次の例は、FIXEDVAL値 ÷ 32bit値を行う fixed_div32を使って、関数ntoa を書き換えたものです。
例2.

/* FIXEDVAL値を 10進数の文字列に変換する */
char        *ntoa(PFIXEDVAL pval,char *pdest)
{
    unsigned long       ulrem;
    char                *pdestorg = pdest;

    while(fixed_nzero(pval,SIZE)){
        fixed_div32(pval,10,&ulrem,SIZE);
        *pdest++ = (char )(ulrem + '0');
    }
    *pdest = 0;
    return strrev(pdestorg);
}

除数ゼロの場合

fixed_div と fixed_div32 は、除数がゼロの場合、計算を行わず戻り値にゼロを返し終了します。
除数がゼロになる可能性がある場合は、関数の戻り値をチェックしてください。
    if (!fixed_div(x, y, ...   width )){

        除数がゼロの時(ゼロ除算エラー)

    }else{

        正常終了時

    }

signed の場合

乗除算は unsigned の計算関数しか無いので、signed の計算を行う場合は数値を絶対値の形にしておく必要があります。
例3.

#define BIT             128
#define SIZE            (BIT / 8)

#define ISNZERO(X)      (fixed_nzero((X),SIZE))            /* X ≠ 0 ? */
#define ISNEG(X)        (((PFIXEDVAL )(X))[SIZE-1] & 0x80) /* X < 0 ? */

/* FIXEDVAL値を 10進数の文字列に変換する */
char        *ntoa(PFIXEDVAL pval,char *pdest)
{
    unsigned long       ulrem;
    char                *pdestorg = pdest,*pstart;

    /* 数値が負の場合は絶対値に変換し、文字列の先頭側に負符号を付ける */
    if (ISNEG(pval)){
        *pdest++ = '-'; fixed_neg(pval,SIZE);
    }

    pstart = pdest;
    while(ISNZERO(pval)){                   /* 継続条件:pval != 0 */
        fixed_div32(pval,10,&ulrem,SIZE);   /* pval /= 10, ulrem = pval % 10 */
        *pdest++ = (char )(ulrem + '0');
    }
    *pdest = 0;

    strrev(pstart);
    return pdestorg;
}