● fixed X

加減算

加減算の関数は、signed と unsigned に分かれています。
unsigned では、fixed_addfixed_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 は負符号を認識しないので、開始位置をずらす必要があります。