C++のabsについて

AI実装検定のご案内

C++のabsは、数値の絶対値を求めるための関数です。

絶対値とは、数直線上で「0からどれだけ離れているか」を表す値です。

そのため、負の数をabsに渡すと符号が取り除かれ、正の値として返されます。

たとえば、次のようになります。

std::abs(-10);  // 10
std::abs(10);   // 10
std::abs(0);    // 0

C++では、標準ライブラリの関数であることを明確にするため、基本的にはstd::absと記述するのがおすすめです。

目次

C++のabsの基本的な使い方

std::absの基本的な書き方は次のとおりです。

std::abs(数値)

たとえば、整数-20の絶対値を求める場合は、次のように記述します。

#include <iostream>
#include <cstdlib>

int main() {
    int value = -20;

    std::cout << std::abs(value) << '\n';

    return 0;
}

実行結果は次のようになります。

20

負の数は正の数として返される

std::absに負の値を渡すと、符号を取り除いた値が返されます。

std::abs(-50);  // 50

一方、もともと正の数であれば値は変化しません。

std::abs(50);  // 50

0を渡した場合は0が返されます。

std::abs(0);  // 0

std::absを使うのがおすすめ

C++では、単にabs()と書くこともありますが、標準ライブラリの関数であることを明確にするため、std::abs()と記述するのがおすすめです。

int result = std::abs(-100);

std::を付けることで、標準名前空間に定義されているabsを使用していることが分かりやすくなります。

特に、規模の大きなプログラムでは同じ名前の関数が定義される可能性もあるため、std::absと明示した方がコードの意図を把握しやすくなります。

整数の絶対値を求める方法

整数の絶対値を求める場合は、std::absintなどの整数を渡します。

#include <iostream>
#include <cstdlib>

int main() {
    int num = -50;

    int result = std::abs(num);

    std::cout << result << '\n';

    return 0;
}

実行結果は次のとおりです。

50

戻り値を直接利用することもできる

絶対値を変数に保存する必要がなければ、そのまま出力や計算に利用できます。

std::cout << std::abs(-50) << '\n';

ほかの計算式と組み合わせることも可能です。

int difference = std::abs(a - b);

このコードでは、abの差の絶対値を求めています。

小数の絶対値を求める方法

std::absは整数だけでなく、浮動小数点数にも使用できます。

たとえば、double型の値に使用する場合は次のように記述します。

#include <iostream>
#include <cmath>

int main() {
    double value = -3.14;

    std::cout << std::abs(value) << '\n';

    return 0;
}

実行結果は次のようになります。

3.14

floatにも使用できる

float型にも使用できます。

float value = -2.5f;
float result = std::abs(value);

long doubleにも使用できる

long doubleにも対応しています。

long double value = -10.25L;
long double result = std::abs(value);

このように、C++のstd::absには複数の数値型に対応したオーバーロードが用意されています。

absを使うときに必要なヘッダ

std::absを使用するときは、対象となる型に対応したヘッダをインクルードします。

整数の場合はcstdlib

整数型のstd::absを使用する場合は、<cstdlib>を使用します。

#include <cstdlib>

たとえば次のように記述します。

#include <cstdlib>

int value = std::abs(-10);

浮動小数点数の場合はcmath

floatdoublelong doubleなどの浮動小数点数に対して使用する場合は、<cmath>を使用します。

#include <cmath>

たとえば次のように記述できます。

#include <cmath>

double value = std::abs(-3.14);

必要な関数が別のヘッダを経由して偶然利用できることもありますが、使用する機能に対応した標準ヘッダを明示的にインクルードするのが安全です。

absとfabsの違い

C++では、絶対値を求める関数としてstd::fabsも用意されています。

std::absstd::fabsは似ていますが、用途に少し違いがあります。

std::absは整数と浮動小数点数に使える

std::absは、整数型や浮動小数点型などに対して利用できます。

std::abs(-10);
std::abs(-3.14);

引数の型に応じた適切なオーバーロードが選択されます。

std::fabsは主に浮動小数点数向け

std::fabsは、主に浮動小数点数の絶対値を求めるために使用されます。

#include <cmath>

double value = -3.14;
double result = std::fabs(value);

現代のC++では、整数と浮動小数点数を同じ名前で扱いたい場合、std::absを利用するとコードを統一しやすくなります。

2つの数値の差を求めるときにabsを使う

std::absは、2つの数値の差の大きさを求めたい場合によく利用されます。

たとえば、次のコードを見てみましょう。

int a = 10;
int b = 25;

int difference = std::abs(a - b);

a - b-15ですが、std::absによって絶対値が計算されるため、differenceには15が格納されます。

数値の大小を事前に調べる必要がない

通常の引き算では、値を並べる順番によって結果の符号が変わります。

10 - 25  // -15
25 - 10  // 15

一方、絶対値を利用すれば、

std::abs(a - b)

とするだけで、どちらの数値が大きいかを事前に判定せずに差の大きさを取得できます。

absを条件判定で使う方法

std::absは、2つの数値がどの程度離れているかを条件判定するときにも便利です。

#include <iostream>
#include <cstdlib>

int main() {
    int a = 100;
    int b = 105;

    if (std::abs(a - b) <= 10) {
        std::cout << "差は10以内です\n";
    }

    return 0;
}

100105の差は5なので、条件が成立します。

位置や点数、時間など、2つの値の距離を判定する処理でも応用できます。

浮動小数点数の比較にabsを使う方法

doublefloatでは、内部表現の都合によって計算結果にわずかな誤差が発生する場合があります。

そのため、浮動小数点数を単純に==で比較するのではなく、2つの値の差が十分に小さいかどうかを調べる方法があります。

#include <iostream>
#include <cmath>

int main() {
    double a = 0.1 + 0.2;
    double b = 0.3;

    if (std::abs(a - b) < 1e-10) {
        std::cout << "ほぼ等しい\n";
    }

    return 0;
}

このコードでは、

std::abs(a - b)

によって2つの値の差を求め、その差が1e-10より小さいかを確認しています。

許容誤差は用途に合わせて決める

ただし、1e-10のような値をすべてのプログラムで使えばよいわけではありません。

適切な許容誤差は、扱う数値の大きさや計算内容によって異なります。

非常に大きな値を比較する場合などは、絶対誤差だけでなく相対誤差を考慮した比較方法が適していることもあります。

absを使わずに絶対値を求める方法

絶対値は、条件演算子を使って自分で計算することもできます。

int x = -10;

int result = x < 0 ? -x : x;

このコードでは、xが負の値なら-xを、0以上ならそのままxを返しています。

ただし、通常は標準ライブラリに用意されているstd::absを使う方が簡潔で、処理の意図も伝わりやすくなります。

int result = std::abs(x);

absを使うときの注意点

std::absは簡単に使える関数ですが、整数型を扱う場合にはいくつか注意点があります。

整数型の最小値には注意する

符号付き整数では、負の方向に表現できる値の方が正の方向より1つ多いことがあります。

たとえば、32ビットのintが次の範囲だったとします。

-2147483648 ~ 2147483647

このとき、

std::abs(-2147483648)

の数学的な絶対値は、

2147483648

です。

しかし、2147483648は同じint型では表現できません。

そのため、絶対値の結果をその型で表現できない値に対してstd::absを使用すると、正常な結果を期待できません。

特にINT_MINなど、符号付き整数型の最小値を扱う場合には注意が必要です。

自分で符号を反転しても同じ問題が起こる

先ほど紹介した、

int result = x < 0 ? -x : x;

という方法でも、xが整数型の最小値だった場合には同じ問題が発生します。

つまり、単純にstd::absを使わず自分で実装すれば安全になるわけではありません。

std::abs(a – b)では引き算のオーバーフローにも注意する

2つの整数の差を求めるとき、

std::abs(a - b)

という書き方は便利ですが、非常に大きな整数を扱う場合には注意が必要です。

たとえば、abの差がintの範囲を超える場合、std::absが実行される前の、

a - b

の段階で問題が発生する可能性があります。

int a = INT_MAX;
int b = INT_MIN;

int difference = std::abs(a - b);

このような極端な値を扱う場合は、より広い整数型へ変換してから計算するなど、オーバーフローを避ける設計が必要です。

通常の小さな整数を扱う処理では大きな問題になりにくいものの、汎用的な関数を作る場合には意識しておきましょう。

unsigned型にabsは基本的に必要ない

unsigned intなどの符号なし整数型は、負の値を表現しません。

そのため、通常は絶対値を求める必要がありません。

unsigned int value = 10;

この値は最初から0以上なので、絶対値を計算する意味がありません。

また、符号なし整数型によってはstd::absへの引数として適切ではなく、呼び出しが成立しない場合もあります。

そのため、unsigned型に対して不要なstd::absを使用するのは避けた方がよいでしょう。

複素数にもabsを使用できる

C++では、<complex>を利用することで複素数にもstd::absを使用できます。

この場合、返されるのは複素数の大きさです。

#include <iostream>
#include <complex>

int main() {
    std::complex<double> z(3.0, 4.0);

    std::cout << std::abs(z) << '\n';

    return 0;
}

実行結果は次のとおりです。

5

複素数3 + 4iの絶対値は、

√(3² + 4²) = 5

となるためです。

std::normとの違いに注意する

複素数では、std::normという別の関数も存在します。

std::absが複素数の大きさを返すのに対して、std::normは大きさの2乗に相当する値を返します。

たとえば、3 + 4iの場合は次のようになります。

std::abs(z);   // 5
std::norm(z);  // 25

名前が似ている機能ではないものの、複素数の計算では混同しないように注意しましょう。

absの戻り値について

std::absは、引数に対応した型の絶対値を返します。

たとえば次のように使用できます。

int x = std::abs(-10);
double y = std::abs(-3.14);

それぞれ、

x = 10
y = 3.14

となります。

戻り値を別の型へ代入するときは注意する

次のように、浮動小数点数の絶対値を整数型へ代入することもできます。

int x = std::abs(-3.14);

ただし、std::abs(-3.14)の結果は3.14ですが、intへ変換される際に小数部分が失われます。

そのため、最終的なxは次のようになります。

3

意図しない精度低下を防ぐためにも、戻り値を受け取る変数には適切な型を使用しましょう。

absを使った実践例

最後に、2つの整数を入力して、その差の絶対値を表示するプログラムを紹介します。

#include <iostream>
#include <cstdlib>

int main() {
    int a;
    int b;

    std::cout << "1つ目の整数: ";
    std::cin >> a;

    std::cout << "2つ目の整数: ";
    std::cin >> b;

    int difference = std::abs(a - b);

    std::cout << "差の絶対値: " << difference << '\n';

    return 0;
}

たとえば、次のように入力します。

1つ目の整数: 10
2つ目の整数: 30

すると、結果は次のようになります。

差の絶対値: 20

このように、std::absは2つの値の距離や差の大きさを求める処理で便利に利用できます。

C++のabsについてのまとめ

C++のabsは、数値の絶対値を求めるための基本的な関数です。

標準ライブラリではstd::absとして利用でき、整数だけでなく、floatdoublelong doubleなどの浮動小数点数にも使用できます。

基本的な書き方は次のとおりです。

std::abs(value)

また、2つの数値の差を求めたり、浮動小数点数がほぼ等しいかを判定したりする処理にも活用できます。

一方で、符号付き整数型の最小値は、その絶対値を同じ型では表現できない場合があります。

さらに、std::abs(a - b)では、std::absを実行する前の引き算でオーバーフローが発生する可能性にも注意が必要です。

符号なし整数型はもともと負の値を持たないため、通常はstd::absを使用する必要はありません。

C++で絶対値を扱う場合は、基本的にstd::absを使用しつつ、数値型の範囲やオーバーフロー、必要なヘッダファイルを意識することが重要です。

以上、C++のabsについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次