"aggregate": Aggregate utility in C
hacker emblem Happy Hacking!


English Here (machine translation)

aggregate: 数値を表す文字列の総和を求めるユーティリティ

この C 言語ユーティリティは、複数の数値を表す文字列を指定して総和あるいは総積を求める aggregate_numbers() こと、数値を表す文字列を数値として比較する compare_numbers() こと、この API で求めた数値を表す文字列を複製する duplicate_numbers() こと、そして、数値を表す文字列を丸める (四捨五入、切り上げ、切り捨て) を行う round_numbers() ものです。数値の桁数には特に制限はありません。


API を使用するためのヘッダは aggregate.h で、API の実装は aggregate.c です。API の説明は、この文書で後述しています。
テスト・プログラム aggregate_test.c そして make ファイル Makefile も記述しました。


API の説明

  1. 数値を表す文字列の総和あるいは総積を求めるユーティリティ: aggregate_numbers()
    char  *aggregate_numbers(Aggregate_e_opcode  opcode
    , const char **numerals
    , size_t n_numerals
    , ssize_t scale
    );

    numerals には数値を表す文字列それぞれのアドレスを収めたポインタ配列のアドレスを指定します。指定した配列から指し示される数値文字列すべてについての演算を行います。
    n_numerals には numerals に指定したポインタ配列の要素数、つまり、総和を求める数値文字列の個数を指定します。

    n_numerlas に 1 を指定した場合、このユーティリティは、opcode に指定する値により単項演算として振舞います。opcode に Aggregate_e_opcode_add, Aggregate_e_opcode_mul のいずれかを指定した場合には numerals[0] に指定した数値文字列と同じ値を持つ数値文字列を、Aggregate_e_opcode_sub を指定した場合には numerals[0] に指定した数値文字列の符号を反転させた結果を、Aggregate_e_opcode_div を指定した場合には numerals[0] に指定した数値文字列の逆数をそれぞれ演算します。

    opcode に Aggregate_e_opcode_add を指定すると数値文字列すべての和 {numerals[n] ; 0 ≦ n ≦ (n_numerals - 1)} を演算します。
    opcode に Aggregate_e_opcode_sub を指定すると最初の数値文字列から残りのすべての数字文字列を差し引いた値 numerals[0] - {numerals[n] ; 1 ≦ n ≦ (n_numerals - 1)} を演算します。
    opcode に Aggregate_e_opcode_mul を指定すると数値文字列すべての積 Π {numerals[n] ; 0 ≦ n ≦ (n_numerals - 1)} を演算します。
    opcode に Aggregate_e_opcode_div を指定すると最初の数値文字列に残りすべての数値文字列の逆数の積をかけた結果 numerals[0] * Π {numerals[n]-1 ; 1 ≦ n ≦ (n_numerals - 1)} を演算します。n_numerals が 2 であれば除算を行うことになります。

    scale にゼロ以上の正数で小数点桁数を指定することで演算結果の精度を制御できます(ゼロを指定すると演算結果は整数になります)。
    scale に負数を指定した場合、opcode が Aggregate_e_opcode_add か Aggregate_e_opcode_sub であれば numerals に指定した数値文字列の中で最大の小数点桁数で演算します。
    opcode が Aggregate_e_opcode_mul であれば numerals に指定した数値文字列すべての小数点桁数の総和に等しい精度で演算します。
    opcode が Aggregate_e_opcode_div であれば numerals に指定した数値文字列の除される数の小数点桁数から除する数の小数点桁数を順次差し引いた桁数の精度で演算します (演算の途中で小数点桁数の差がゼロ以下になった場合は整数精度で演算します)。

    注意 opcode に aggregate_e_opcode_mul を指定した場合、numerals に指定した数値文字列の個数が多くなると、演算途中で獲得する動的メモリが不足したり、処理に長大な時間がかかってしまう恐れがあります。opcode に Aggregate_e_opcode_mul を指定する場合は、一度に多くの数値文字列を numerals に指定しないように注意してください。

    正常終了した場合、演算結果を表す数値文字列を収めた動的メモリのアドレスが返されます。返されたアドレスを destroy_aggregate_numbers() に渡すことでメモリ解放します。
    なんらかのエラーが発生した場合は、戻り値に NULL が返ります。発生したエラーの詳細は以下のように errno に出力されます。

    • EINVAL (= 22) : 不正な引数が渡された場合
    • ENOMEM (= 12) : 作業メモリに割り当てる動的メモリが獲得できない場合 (システムメモリ不足)
    • EDOM (=33) : ゼロで除算した場合 (Aggregate_e_opcode_div の場合のみ)

  2. aggregate_numbers() で求めた演算結果を収めた動的メモリを解放する destroy_aggregate_numbers()
    int  destroy_aggregate_numbers(char  *aggregate_numbers_result);

    aggregate_numbers_result に aggregate_numbers() の戻り値を渡して、演算結果を収めている動的メモリを解放します。

    正常に終了した場合はゼロを、エラーが発生した場合は非ゼロが返されます。
    発生したエラーの詳細は、以下のように errno に出力されます。

    • EINVAL (= 22) : 不正な引数が渡された場合

  3. 任意の桁数の数値を表す文字列を、数値として比較するユーティリティ compare_numbers()
    int  *compare_numbers(const char  *a_str
    , const char *b_str
    , int *result
    );

    int is_number_zero(const char *num);

    a_str と b_str には比較する数値を表す文字列それぞれのアドレスを指定します。
    result には a_str と b_str を比較した結果を、a_str が b_str よりも小さい数値を表しているならば -1、a_str と b_str が等しい数値を表しているならばゼロ、a_str が b_str よりも大きな数値を表しているならば 1 として、出力します。

    is_number_zero() に数値を表す文字列のアドレス num を渡すと、その文字列が数値としてのゼロを表しているかいなかを判定します。空文字列 ("") や符号 ('+', '-') だけの文字列もゼロを表すものと解釈します。

    正常終了した場合、result に演算結果が出力され、そのアドレスが返されます。
    なんらかのエラーが発生した場合は、戻り値に NULL が返ります。発生したエラーの詳細は以下のように errno に出力されます。

    • EINVAL (= 22) : 不正な引数が渡された場合

  4. 任意の桁数の数値を表す文字列の複製を生成するユーティリティ duplicate_numbers()
    char  *duplicate_numbers(const char  *num);

    num には数値を表す文字列のアドレスを指定します。

    正常終了した場合、戻り値に NULL 以外のアドレス値を返します。
    何らかのエラーが発生した場合は、NULL を返し、errno に以下のエラー原因を出力します。

    • EINVAL (= 22) : 不正な引数が渡された場合
    • ENOMEM (= 12) : 作業メモリに割り当てる動的メモリが獲得できない場合 (システムメモリ不足)

  5. 任意の桁数の数値を表す文字列を丸める (四捨五入、切り上げ、切り捨て) ユーティリティ round_numbers()
    char  *round_numbers(Aggregate_e_round_how  how
    , const char *num
    , ssize_t round_scale
    );

    how には丸めの方法を指定します。四捨五入は Aggregate_e_round_even、 切り上げは Aggregate_e_round_up、切り捨ては Aggregate_e_round_down を指定します。
    num には丸める数値を表す文字列のアドレスを指定します。
    round_scale には、丸める小数部の桁位置 (小数第一位は 1、小数第二位は 2、…) か、丸める整数部の桁位置 (一の位は 0、二の位は -1、…) を指定します。

    正常終了した場合、丸めた結果の数値を表す文字列へのアドレス (NULL 以外) を返します。
    なんらかのエラーが発生した場合は、NULL を返し、errno に以下のエラー原因を出力します。

    • EINVAL (= 22) : 不正な引数が渡された場合
    • ENOMEM (= 12) : 作業メモリに割り当てる動的メモリが獲得できない場合 (システムメモリ不足)

  6. 任意の桁数の数値を表す文字列の絶対値を求めるユーティリティ absolute_numbers()
    char  *absolute_numbers(const char  *num, ssize_t  scale)

    num には絶対値を求める数値を表す文字列のアドレスを指定します。
    scale には求める絶対値の小数部桁数をゼロ以上の数値で指定します。負数を指定した場合は、num に指定した数値文字列の小数部桁数と同じ桁数になります。

    正常終了した場合、絶対を表す数値文字列をメモリ獲得したアドレスを返します。
    なんらかのエラーが発生した場合は NULL を返し、errno に以下のエラー原因を出力します。

    • EINVAL (= 22) : 不正な引数が渡された場合
    • ENOMEM (= 12) : 作業メモリに割り当てる動的メモリが獲得できない場合 (システムメモリ不足)