|
|
|
| 2008/10/07 11:47||▲
|
|
|
勢いに乗ってきたので、どんどん書きます。
div関数は、整数どうしの除算における商と剰余を同時に求めるための関数で、int型用がdiv、long型用がldiv、long long型用がlldivという名前になります。
C99より前は、一方のオペランドが負で、他方が正の除算の結果は処理系定義でしたので、div関数の実装では、一旦引数の絶対値を求めてから商と剰余を求め、後で調整する方式をとっていましたが、C99では、その必要もなくなりました。単に機能を満たすだけであれば、次の実装で十分です。
typedef struct { int quot; int rem; } div_t;
div_t div(int numer, int denom) { div_t result; result.quot = numer / denom; result.rem = numer % denom; return result; }
このように書くと、返却値のコピーが懸念されるのですが、実際のコンパイル結果を見る限りでは問題ありませんでした。
ところで、H8/300HやH8Sで、int型が16ビットの場合には、上記の実装で理想的なコードが出力されました。というのは、H8の除算命令を使って、商と剰余を同時に求めるように展開されていたのです。
ところが、int型が32ビットであったり、H8/300の場合は、そううまくはいきませんでした。H8/300は用途が少ないので無視するとしても、実行環境であるTOPPERS/JSPカーネルでは、int型を32ビットにしているので、結構大きな問題になります。
剰余の計算を、numer - result.quot * denomとすれば多少はましですが、できれば商と剰余を一発で求めたいものです。これについては、もう少し検討を続けたいと思います。
ldivおよびlldivに関しても、div関数と基本的には同じですが、16ビット以下になることはないので、はじめから剰余の求め方を変えておきます。
typedef struct { long quot; long rem; } ldiv_t;
ldiv_t ldiv(long numer, long denom) { ldiv_t result; result.quot = numer / denom; result.rem = numer - result.quot * denom; return result; }
typedef struct { long long quot; long long rem; } lldiv_t;
lldiv_t lldiv(long long numer, long long denom) { lldiv_t result; result.quot = numer / denom; result.rem = numer - result.quot * denom; return result; }
C++のdiv関数は、int型用だけではなく、long型用のものも多重定義されています。標準C++ではlong long型はサポートされませんが、GCCではサポートされるので、ついでにlong long型用のものも多重定義しておきましょう。
#ifdef __cplusplus inline ldiv_t div(long __numer, long __denom) { return ldiv(__numinline lldiv_t div(long long __numer, long long __denom) { return lldiv(__numer, __denom); } #endif
|
| 2006/05/24 00:52|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
コメント
|
|
コメントの投稿
|
|
|
|
|
トラックバック
|
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/58-99b845e3
|
|
|
|
|
ホーム
全記事一覧
<< 前の記事
次の記事 >>
|