● 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);
}
上記は「文字列の式を計算し、その結果を表示して終了する」という、最も簡単な例です。
- 最初に関数fixedutil_strcalc_init で環境の初期化
- 関数fixedutil_strcalc で実際の計算を行う
- 最後に関数fixedutil_strcalc_term で環境を破棄する
これらの呼び出しはセットで行われますが、計算毎に行う必要はありません(プログラムの仕様によっては、2 が複数回繰り返される場合もある)。
- StrCalc 環境と初期化
StrCalc では、FIXED_STRCALC_PARAM構造体の実体一つが、一つの計算環境になります。実体を関数fixedutil_strcalc_init で初期化し、関数fixedutil_strcalc で使用、終了時には関数fixedutil_strcalc_term で破棄します。
- fixedutil_strcalc_init で開始した計算環境の数値幅は、fixedutil_strcalc_term で終了するまで続きます(途中で変える事はできない)。
数値幅の異なる計算を行いたい場合は、数値幅の種類分 StrCalc 環境を用意し、使い分ける事で行えます。
- fixedutil_strcalc_init の3つ目の引数には、ユーティリティーで作成した FIXEDVAL値の一次元配列を指定します。これは、StrCalc の「文法上のメモリ」として扱われます。StrCalc 上で文法上のメモリを使用しない場合は、引数に NULL を設定します。
配列は、fixedutil_strcalc_init 実行後であれば、直に FIXED_STRCALC_PARAM構造体の実体に設定する事もできます。
- StrCalc は、処理に必要なワークエリアの確保に、MEMFUNC構造体で指定されたメモリ確保・解放関数を使用します(StrCalc については、例外的に関数自体がワークエリア確保を行う)。
メモリの確保・解放関数は MEMFUNC構造体 に格納し、その実体のアドレスを設定します。
- StrCalc の実行
関数fixedutil_strcalc に初期化した環境を指定して実行すると、計算を開始します。
- 関数実行前に、FIXED_STRCALC_PARAM構造体のメンバ str へ、計算対象の文字列を格納した領域のアドレスをセットします。この文字列は末尾ヌルである必要があります。
文字列の式には記述規則があります。「StrCalc 計算式規則」を参照してください。
- もし、文法上のメモリを使用しないのであれば、メンバ pmem に NULLを設定する事ができます。NULL設定状態で文字列内にメモリ表現があると、エラーで計算を終了します。
- 戻り値が STATUS_NORMAL で終了した場合、メンバ pans が指す領域に結果が格納されています。
pans が指す領域は自動で確保されます。数値幅は初期化時に設定したものになり、対象の環境で関数fixedutil_strcalc_term が実行されるまで存在し続けます。
計算に必要な設定は関数fixedutil_strcalc を呼び出す前に行う必要がありますが、fixedutil_strcalc_init を呼び出す前には行わないでください。fixedutil_strcalc_init は、初期化処理を開始する前に、FIXED_STRCALC_PARAM構造体の実体をゼロクリアします。
- 環境の破棄
使わなくなった 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 |
関数の引数指定に誤りがある事を意味します。
このエラーは使用上のエラーではなくプログラム側の問題なので、リリース版では出てはいけないエラーです。 |