● 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;
}