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


English Here (machine translation)

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

この C 言語ユーティリティは、任意の計算精度で以下の演算を行うためのものです。


数値の桁数には特に制限はありません。


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 を渡すと、その文字列が数値としてのゼロを表しているかいなかを判定します。空文字列 ("") や符号 ('+', '-') だけの文字列もゼロを表すものと解釈します。
    ゼロを表していると解釈できる場合は非ゼロを、そうでなければゼロを返します。また、与えられた引数が不正なものである場合には、エラーを返すために INT_MIN を返します。

    正常終了した場合、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) : 作業メモリに割り当てる動的メモリが獲得できない場合 (システムメモリ不足)

  7. 任意の精度の平方根を求めるユーティリティ sqrt_numbers()
    char  *sqrt_numbers(const char  *num, ssize_t  scale)

    num には平方根を求める数値を表す文字列のアドレスを指定します。
    scale には求める平方根の小数部桁数をゼロより大きな数値で指定します。ゼロか負数を指定した場合は、整数部まで平方根を求めます。

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

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

  8. 任意の精度の指数関数ユーティリティ exponent_numbers()
    char  *exponent_numbers(const char  *num, ssize_t  scale)

    num にはネイピア数 e (≒ 2.718) の冪数を表す文字列のアドレスを指定します。
    scale には求めるネイピア数の冪乗の小数部桁数をゼロより大きな数値で指定します。ゼロか負数を指定した場合は、整数部までを求めます。

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

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

  9. 任意の精度の自然対数を求めるユーティリティ ln_numbers()
    char  *ln_numbers(const char  *num, ssize_t  scale)

    num にはネイピア数 e (≒ 2.718) を底とする対数 (自然対数) を求める数値を表す文字列のアドレスを指定します。
    scale には求める自然対数の小数部桁数をゼロより大きな数値で指定します。ゼロか負数を指定した場合の結果は保証されません。

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

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

  10. ゼロを表す文字列を生成するユーティリティ make_zero_numbers()
    char  *make_zero_numbers(ssize_t  scale)

    scale に生成するゼロを表す文字列の小数部桁数をゼロより大きな数値で指定します。ゼロか負数を指定した場合は整数部だけのゼロ ("0") を返します。

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

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

  11. 10 の整数冪乗を求めるユーティリティ make_power_of_ten()
    char  *make_power_of_ten(ssize_t  scale)

    scale に整数冪数を表す数値を指定します。求まる整数冪乗は、10^(-scale) になります (通常の冪数の指定とは符号の意味が異なりますので、注意してください)

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

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

  12. 数値を指定された桁数分シフトするユーティリティ shift_numbers()
    char  *shift_numbers(const char  *num, ssize_t  scale)

    num には桁シフトを行う数値を表す文字列のアドレスを指定します。
    scale にはシフトする桁数を指定します。ゼロより大きな数値を指定すると、桁を右方向にシフトします。ゼロより小さな数値を指定すると、桁を左方向にシフトします。つまり、シフトの結果は num × 10^(-scale) になります。
    ゼロを指定した場合はシフトはしません。

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

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