整数の絶対値は常に正の数になるとは限らないJavaTips 〜Javaプログラミング編

» 2006年11月01日 10時00分 公開
[平野正喜@IT]

 数値の絶対値を得たい場合、Math.absメソッドを使う方法と、自前で「負の数であれば符号を逆転する」方法がありますが、実はJavaでは「そのどちらを用いても」結果が必ず正の数になるとは限りません。

 具体的には、int型およびlong型の最小値の絶対値を得ようとした場合で、下図のとおり、Math.absメソッドを用いても、符号を逆転しても、元の値が返ってきますので「絶対値を取ったはずが、負の数が返ってくる」となります。

int型、long型の最小値の絶対値は解法にかかわらず元の値に等しい負の数 int型、long型の最小値の絶対値は解法にかかわらず元の値に等しい負の数

 これは、int型の最大値(2,147,483,647)が、最小値(-2,147,483,648)の絶対値よりも、1小さいことが原因であり、long型、short型、byte型の場合も同様です。

 Javaではこのことへの対処として、例外を発生させたり、範囲外を示すビットパターンを返したりせずに、そのままの値を返すことを明文化しているわけです。

 なお、実数においてはこの現象は起こらないため、float型や、double型では絶対値が負の数になることはありません(NaNの場合のみ、NaNを返します)。

 さて、short型とbyte型の場合、Math.absメソッドには対応するシグニチャがありませんが、暗黙の型変換によりint型として扱われますので、そのままMath.absメソッドに渡すことができます。しかし、戻り値もint型となってしまいますので、元の型で用いるにはキャストする必要があります。

 また、short型、byte型の最小値に対して、符号の逆転で絶対値を得ることはできますが、この結果は元の型ではなく強制的にint型にされてしまいます。その結果、例えば「short shortAbsMin = -(Short.MIN_VALUE);」という式は「型の不一致: int から short には変換できません」というコンパイルエラーになってしまうのです。型を変えずにこのコンパイルエラーを避けるにはキャストするしかありません。

 この2つのパターンを試してみると下図のようになります。結果を見てのとおり、この場合においても、「最小値の絶対値は解法にかかわらず元の値に等しい負の数」になってしまうのです。

short型、byte型の最小値の絶対値は元の型にキャストすると元の値に等しい負の数 short型、byte型の最小値の絶対値は元の型にキャストすると元の値に等しい負の数

 以上から、「整数の絶対値は常に正の数になる」という前提でのプログラミングは避けた方がよいことが分かります。

Profile

RunDog.org

平野正喜


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。