● StrCalc の実装

5.数学関数、定数の登録

StrCalc Ver 3.9 では、ユーザが数学関数や定数を登録する事ができます。

5−1. 数学関数の登録

例1. 

#include <stdio.h>
#include "sc39.h"

double __stdcall    user_f_Celsius(double *,int ,int *,void *);

void    main(void)
{
    STRCALC_PARAM       prm;
    int                 ret;

    if (!StrCalc_init(&prm)){
        printf("メモリの確保に失敗しました\n");
        return;
    }

    if (StrCalc_setfunc(&prm,"celsius",1,user_f_Celsius,NULL) <= 0){
        StrCalc_term(&prm);
        printf("ユーザ関数の登録に失敗しました\n");
        return;
    }

    prm.str = "celsius(77)";

    ret = StrCalc(&prm);

    StrCalc_term(&prm);

    if (ret != STATUS_NORMAL)
        printf("error.  %d\n",ret);
    else
        printf("ans. : %.16G\n",prm.ans);
}

double __stdcall    user_f_Celsius(double *arg,int argcnt,int *pret,void *param)
{
    *pret = STATUS_NORMAL;

    return 5 * (arg[0] - 32) / 9;
}
例1ソースファイル(zip)

この例では、華氏をセルシウス度に変換する関数を登録しています。登録には関数StrCalc_setfunc を使用します(削除には関数StrCalc_delete_userfunc または 関数StrCalc_term を使用)。

ユーザ定義の数学関数には、計算処理を行うためのコールバック関数を用意する必要があります。StrCalc の計算式内でユーザ関数が使用された場合、上記の例では関数user_f_Celsius が呼び出されます。
数学関数のコールバック関数は、戻り値の返し方が他と異なります。処理の結果に応じて、状態コード を引数pret の指す int型領域に渡し、計算結果を戻り値で返します。

param には、関数StrCalc_setfunc で渡した追加パラメータがそのまま渡されます。マルチスレッド化する場合等、グローバル変数を使用せずに情報を渡す必要がある時に使用する事ができます。

数学関数のコールバック関数内では、呼び出し元の STRCALC_PARAM 構造体 の実体を使って、StrCalc の計算処理を行わないでください(コールバック関数MFUNC の「注意点」参照の事)。


5−2. 定数の登録

例2. 

#include <stdio.h>
#include "sc39.h"

void    main(void)
{
    STRCALC_PARAM       prm;
    int                 ret;

    if (!StrCalc_init(&prm)){
        printf("メモリの確保に失敗しました\n");
        return;
    }

    if (StrCalc_setconst(&prm,"std_g",9.80665) <= 0 ||
        StrCalc_setconst(&prm,"radius_earth",6378000.0) <= 0){
        StrCalc_term(&prm);
        printf("定数の登録に失敗しました\n");
        return;
    }

    prm.str = "sqrt(std_g * radius_earth)";

    ret = StrCalc(&prm);

    StrCalc_term(&prm);

    if (ret != STATUS_NORMAL)
        printf("error.  %d\n",ret);
    else
        printf("ans. : %.16G  [m/s]\n",prm.ans);
}
例2ソースファイル(zip)

定数の登録には関数StrCalc_setconst を使用します。
StrCalc での定数は読み取り専用で、書き込みは行えません。また、定数は関数StrCalc_termでなければ削除する事はできません。


Ver 3.9 では変数、数学関数、定数が一元管理されており、数学関数名、定数名も変数名と同じ規則が適用されます(変数名の規則については計算式規則参照の事)。