● fixed X
加減算
加減算の関数は、signed と unsigned に分かれています。
unsigned では、fixed_add 、fixed_sub を使用します。
例1.1156262128751139 + 6643456757654475 を計算し、結果を 10進数で表示
#include <stdio.h>
#include "fixedX.h"
#define BIT 128
#define SIZE (BIT / 8)
void main(void )
{
FIXEDVAL a[SIZE],b[SIZE];
char buf[39+1];
fixed_atoui(a,SIZE,"1156262128751139"); /* a に値をセット */
fixed_atoui(b,SIZE,"6643456757654475"); /* b に値をセット */
fixed_add(a,b,SIZE); /* 加算 */
fixed_num2str10(a,SIZE,buf); /* 結果を文字列に変換 */
printf("%s\n",buf);
}
加算の結果は、引数 a に指定したアドレスの領域(被加数が格納されていた FIXEDVAL領域)に上書きで格納されます。
関数の引数を、
fixed_add(a,b,width );
とした場合、加算の処理は、
a += b
を計算しているのと同じです(width は数値幅)。
減算も同様に、
fixed_sub(a,b,width ); → a -= b
となります。元の値が必要な場合は、関数を実行する前に、内容を別の領域に退避しておく必要があります。
なお、2つ以上の FIXEDVAL変数を指定する計算関数の場合、基本的にはそれらの数値幅は同じである必要があります(一部例外あり)。数値幅の異なる FIXEDVAL変数同士を直に計算させる事はできません。
符号付き加減算
signed の加算を行う場合は関数fixed_signed_add 、減算は関数fixed_signed_sub を使用します。
例2.
#include <stdio.h>
#include "fixedX.h"
#define BIT 128
#define SIZE (BIT / 8)
void main(void )
{
FIXEDVAL a[SIZE],b[SIZE];
char buf[40+1];
int s,of;
fixed_atoui(a,SIZE,"170141183460469231731024565126536546705"); /* a に値をセット */
fixed_atoui(b,SIZE,"662738589347559023"); /* b に値をセット */
of = fixed_signed_add(a,b,SIZE); /* signed 加算 */
/* 結果が負の場合、正に変換する */
if (a[SIZE - 1] & 0x80){
fixed_neg(a,SIZE);
s = '-';
}else
s = ' ';
fixed_num2str10(a,SIZE,buf); /* 結果を文字列に変換 */
printf("%c%s ... of : %d\n",s,buf,of);
}
signed の関数は、加減算の結果のオーバーフロー状態を戻り値として返します。例2 の結果は 128bit の正の範囲を超え、負の値 -170141183460469231731687303715884105728(0x80000000000000000000000000000000 )となるので、戻り値に 1 を返します。
符号反転
関数fixed_num2str10 は unsigned の値を文字列に変換する関数なので、値が負の場合は正に変換する必要があります。
・
・
・
/* 結果が負の場合、正に変換する */
if (a[SIZE - 1] & 0x80){
fixed_neg(a,SIZE);
s = '-';
}else
s = ' ';
・
・
・
MSB で正負を判断できる事は、「FIXEDVAL値」の「値の性質」で述べた通りです。
値が負の場合、関数fixed_neg を使って正に変換します。
fixed_neg(a,width ); → a = -a
fixed_neg は 2 の補数を計算します。関数に与える値が負の場合は正となり、正の場合は負となります。
入力も表示と同様の改良をする事ができます。
関数fixed_atoui は unsigned の数値文字列を FIXEDVAL値に変換するので、そのままでは負符号が使えません。
例3.
#include <ctype.h>
#include "fixedX.h"
void fixed_atoui_customized(PFIXEDVAL pval,int size,char *pstr)
{
while(isspace(*pstr)) pstr++; /* 最初の空白文字列を飛ばす */
/* 負の場合は、結果を符号反転する */
if (*pstr == '-'){
fixed_atoui(pval,size,pstr + 1);
fixed_neg(pval,size);
}else
fixed_atoui(pval,size,pstr);
}
この関数では、入力した文字列の先頭に負符号があった場合、変換した数値を符号反転します。
負の場合の数値変換で、pstr を一つ進めて指定している事に注意してください。関数fixed_atoui は負符号を認識しないので、開始位置をずらす必要があります。