[迷信] abs は常に非負の値を返す

abs 関数というのは絶対値を求める関数です。C では int 型の引数を受け取り int 型の値を返します。C++ では、int 版以外に、long 版、float 版、double 版、long double 版、std::complex クラステンプレート版が多重定義されています。絶対値を求める関数ですから、ゼロまたは正の値を返すのが数学的に正しい振る舞いです。

ところが、現実には必ずしもそうはならない場合があります。まずは、浮動小数点数や複素数の引数として非数(NaN)が渡された場合がそうです。これについては、それほど大きな問題になることはないでしょう。問題は整数の場合です。

abs 関数に INT_MIN を与えた場合を考えてみてください。負の値の内部表現に 2 の補数を使う処理系(実質的にすべての処理系と考えても、あながち間違いとはいえません)では、INT_MIN の絶対値は INT_MAX + 1 になることが大多数です。つまり、INT_MIN の絶対値を int 型で表現することができなくなるのです。

abs 関数は、結果が表現できない場合の動作は未定義です。多くの場合、abs(INT_MIN) は INT_MIN(すなわち負の値)を返します。つまり、非ゼロではない値を返すわけです。

他の可能性についても考えてみます。

負の値の内部表現は 2 の補数だけれども、符号ビットとすべての値ビットが 1 となるようなビットパターンがトラップ表現になる処理系も考えられます。この場合には、abs(INT_MIN) は INT_MAX になりますので問題ありません。ただし、引数にトラップ表現を与えた場合の動作は未定義になります。

負の値の内部表現に 1 の補数または符号ビットと絶対値を使う場合にも、abs(INT_MIN) は INT_MAX になります。ただし、この場合もトラップ表現を引数として与えた場合の動作は未定義になります。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/622