● fixed X ユーティリティー

StrCalc

「StrCalc」は、文字列の数式を計算する処理の名称です。文字列として記述されている式を計算し、結果を数値型で返します。fixed X とは別に、double型ベースのライブラリが幾つか公開されています。

fixed X のユーティリティーには、FIXEDVAL型を計算する StrCalc が組み込まれています。
    "(34235346364323548235 * 93767899267 + 234111124565) / 8 - 44564758785865465"
このような式の数値部分を FIXEDVAL値として取り込み、整数演算を行い、結果を FIXEDVAL型で返します。

この機能の用途はさまざまです。初期化ファイルのスクリプト処理に利用する事もできますし、ユーザインターフェースを用意して、そのまま電卓として利用する事もできます。また、本来はプログラム内で行う固定の計算を文字列(データ)として扱い、それを計算させる「プログラムの一部」としても利用する事ができます。


使用手順

StrCalc を使用するには、開始、終了の手続きが必要です。多少煩雑になりますが、順を追って用意すれば良いだけなので、決して難しくはありません。
例.

#include <stdio.h>
#include <stdlib.h>
#include "fixedX.h"
#include "fixutil.h"

/* メモリの確保・解放コールバック */
void * __stdcall        fx_alloc(size_t size,void *param)
{
    return malloc(size);
}

void __stdcall          fx_free(void *pmem,void *param)
{
    free(pmem);
}

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

void    main(void )
{
    MEMFUNC                 memfunc;
    FIXED_STRCALC_PARAM     prm;
    FIXEDVAL                work[SIZE];
    char                    buf[128];
    int                     ret;

    /*
      メモリ確保・解放関数のポインタ
      この情報も、prm の中に組み込まれます。
    */
    memfunc.pfmemalloc = fx_alloc;
    memfunc.pfmemfree = fx_free;

    /*
      FIXED_STRCALC_PARAM構造体の実体に StrCalc の環境を作成する
      この時のエラーチェックは必ず行ってください。
    */
    ret = fixedutil_strcalc_init(
                    &prm,         /* StrCalc 環境 */
                    SIZE,         /* この環境で使用する数値幅 */
                    NULL,         /* 文法上のメモリ */
                    &memfunc);    /* メモリ確保・解放処理のポインタ */
    if (ret != STATUS_NORMAL){
        printf("初期化エラー\n");
        return;
    }

    /*
      計算対象の文字列
      結果は 401272063657548579457414980573
    */
    prm.str = "(34235346364323548235 * 93767899267 + 234111124565) / 8 - 44564758785865465";

    /* 計算 */
    if ((ret = fixedutil_strcalc(&prm)) != STATUS_NORMAL){
        fixedutil_strcalc_term(&prm);
        printf("計算エラー:%s\n",fixedutil_errormes(ret));
        return;
    }

    fixedutil_signed_num2str(prm.pans,SIZE,10,buf,work); /* 結果を文字列に変換 */
    printf("結果:%s\n",buf);

    /* StrCalc の環境を破棄 */
    fixedutil_strcalc_term(&prm);
}
上記は「文字列の式を計算し、その結果を表示して終了する」という、最も簡単な例です。

  1. 最初に関数fixedutil_strcalc_init で環境の初期化
  2. 関数fixedutil_strcalc で実際の計算を行う
  3. 最後に関数fixedutil_strcalc_term で環境を破棄する
これらの呼び出しはセットで行われますが、計算毎に行う必要はありません(プログラムの仕様によっては、2 が複数回繰り返される場合もある)。


  1. StrCalc 環境と初期化
  2. StrCalc では、FIXED_STRCALC_PARAM構造体の実体一つが、一つの計算環境になります。実体を関数fixedutil_strcalc_init で初期化し、関数fixedutil_strcalc で使用、終了時には関数fixedutil_strcalc_term で破棄します。

  3. StrCalc の実行
  4. 関数fixedutil_strcalc に初期化した環境を指定して実行すると、計算を開始します。

    計算に必要な設定は関数fixedutil_strcalc を呼び出す前に行う必要がありますが、fixedutil_strcalc_init を呼び出す前には行わないでください。fixedutil_strcalc_init は、初期化処理を開始する前に、FIXED_STRCALC_PARAM構造体の実体をゼロクリアします。


  5. 環境の破棄
  6. 使わなくなった StrCalc 環境を関数fixedutil_strcalc_term により破棄します。fixedutil_strcalc_term は、環境内にあるワークエリアの解放等を行います。
    関数fixedutil_strcalc_init で初期化された環境は、不要になったら必ず fixedutil_strcalc_term で破棄してください(fixedutil_strcalc_init が STATUS_NORMAL で終了した時の環境は、必ず fixedutil_strcalc_term で破棄する)。


関数fixedutil_strcalc が返す状態コード

関数fixedutil_strcalc は計算式で発生したエラーを状態コードで返します。一つのコードに複数の意味がある事が、他の関数が返した場合とは異なります。

状態コード意味
STATUS_ERROR 計算式に誤りがある事を意味します。主に文法エラーです。

  • 演算子の数と項数が合わない場合、または演算子の使用法に誤りがあった場合。
  • 基数指定文字が規則外の場合。
  • 数値文字列に、数値に変換できない文字が含まれていた場合。
  • 関数、置き換え文字のスペルに誤りがあった場合。
  • 文字定数の記述に誤りがあった場合。
STATUS_DIVIDEBYZERO 除算、剰余計算で、除数にゼロが指定された事を意味します。
STATUS_ILLEGALPARENTHESIS 括弧の記述に誤りがある事を意味します。
括弧の数が合わない、順序が逆、16階層を超えた場合等。
STATUS_MEMERROR メモリ表現に誤りがある事を意味します。

  • メモリインデックスの計算式にエラーがある場合。
    式のエラーがどのようなものであっても、STATUS_MEMERROR を返します。

  • インデックスの値が、アクセスできるメモリ範囲を超えた場合。

  • FIXED_STRCALC_PARAM構造体のメンバ pmem に NULL を指定しているのに、メモリ表現が使われた場合。

  • メモリ表現の記述に誤りがある場合。
    角括弧の数が合わない、順序が逆、16階層を越えた場合等。
STATUS_TOOMANYITEM 項数が多過ぎる事を意味します。
STATUS_INVALIDARGS (文法上の)関数の引数の記述に誤りがある事を意味します。
引数の過不足や、区切り方に問題がある場合等。
STATUS_ILLEGALFUNCTIONCALL 規則に定められた範囲外の引数で(文法上の)関数を使用した事を意味します。
STATUS_RANGEOVER オーバーフローが発生した事を意味します。
STATUS_TOOLONGNUM 数値が長過ぎる事を意味します。
STATUS_NOTENOUGHMEM メモリが確保できなかった事を意味します。
STATUS_PARAMERROR 関数の引数指定に誤りがある事を意味します。
このエラーは使用上のエラーではなくプログラム側の問題なので、リリース版では出てはいけないエラーです。