|
ホーム
全記事一覧
<< 前の記事
次の記事 >>
|
|
| abs関数は、整数の絶対値を求める関数で、int型用がabs、long型用がlabs、long long型用がllabsという名前になります。浮動小数点数用のものは<math.h>ヘッダで、複素数用のものは<complex.h>ヘッダでそれぞれ宣言されますので、ここで扱うのは整数用のものだけです。
実装はいたって簡単で、次のようになります。
int abs(int j) { return j < 0 ? -j : j; }
labsおよびllabs関数も同様に実装することができますので、ここでは割愛します。この関数は非常に単純ですので、<stdlib.h>ヘッダ内でインライン関数として定義しておき、ユーザーが自分で関数原型を書いて呼び出したときのためだけに、外部定義も用意しておくことにします。
念のため、インライン関数の定義も挙げておきます。
static inline int abs(int __j) { return __j < 0 ? -__j : __j; }
jを予約済み識別子である__jに変更する以外は、特にこれといった違いはありません。
ところで、このabs関数ですが、引数がINT_MINの場合には、結果もINT_MINになってしまいます。標準規格では、結果が表現できない場合の動作は未定義なので、これでも問題ないのですが、ときどき罠にはまるので注意が必要です。
参考までに、今回は条件演算子を使ってあっさり実装しましたが、RISCのように分岐のコストが大きいプロセッサでは、次のように実装することがあります。
int t = j >> (sizeof(j)*CHAR_BIT-1); return (j ^ t) - t;
確かにこれで分岐はなくなります。H8の場合には、シフト演算のコストが分岐以上に大きいので、こうした実装は最適とはいえません。
C++のabs関数は、int型だけでなく、long型、float型、double型、long double型それぞれについて多重定義されています。long long型は標準C++ではサポートされないのですが、GCCではサポートされるので、long long型についても多重定義しておいた方がよいでしょう。
#ifdef __cplusplus inline long abs(long __j) { return __j < 0 ? -__j : __j; } inline long long abs(long long __j) { return __j < 0 ? -__j : __j; } inline float abs(float __x) { return __x < 0 ? -__x : __x; } inline double abs(double __x) { return __x < 0 ? -__x : __x; } inline long double abs(long double __x) { return __x < 0 ? -__x : __x; } #endif
他の型のものを勝手に定義してしまうわけにはいかないので、テンプレートは使わず、多重定義によって実装する必要があります。
スポンサーサイト
| 2006/05/24 00:19|一般ユーティリティ|TB:0|CM:0|▲
|
|
コメント
|
コメントの投稿
|
|
|
トラックバック
|
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/57-0a266884
|
|
|
ホーム
全記事一覧
<< 前の記事
次の記事 >>
|
|
|