閉じる

C言語の絶対値計算まとめ abs・labs・llabs・fabsの使い分け

C言語で絶対値を求めるときは、整数と浮動小数点で使う関数が異なります。

本記事では、abs・labs・llabs・fabsの4種類を「どの型で使うか」「どのヘッダを読むか」「オーバーフローは大丈夫か」まで丁寧に整理します。

初心者の方でも安全に使えるよう、注意点や実行例を交えて解説します。

絶対値の基本

絶対値とは

絶対値とは、数値の符号(プラス・マイナス)を取り除いた大きさのことです。

例えば -3 の絶対値は 3、3 の絶対値は 3 になります。

絶対値は「0からどれだけ離れているか」を表す量であり、距離や誤差の評価で頻繁に使われます。

4つの関数と対応する型

C言語の標準ライブラリには、次の4つの絶対値関数があります。

整数にはabs・labs・llabs、小数にはfabsを使います。

関数名と対応する型は次の通りです。

関数引数の型戻り値の型主な用途宣言ヘッダ
absintint通常の整数(int)の絶対値<stdlib.h>
labslonglonglong型の絶対値<stdlib.h>
llabslong longlong longlong long型(64bit相当)の絶対値<stdlib.h>
fabsdoubledouble小数(double)の絶対値<math.h>

補足として、小数にはfloat版のfabsflong double版のfabslもありますが、本記事ではfabs(double)を中心に説明します。

ヘッダファイル

  • abslabsllabs<stdlib.h>に宣言されています。
  • fabs<math.h>に宣言されています。
  • 定数の最小値/最大値を扱うときは<limits.h>が、浮動小数点の範囲や特性を知るときは<float.h>が役立ちます。

最小限のインクルード例は次の通りです。

C言語
// 最小限のインクルード例
#include <stdlib.h>  // abs, labs, llabs
#include <math.h>    // fabs
#include <limits.h>  // INT_MIN, LONG_MIN, LLONG_MIN
#include <float.h>   // DBL_MAX など

オーバーフローに注意

整数の最小値(INT_MINなど)に対して絶対値を計算すると、結果が同じ型に収まらず未定義動作になることがあります。

例えば多くの環境でINT_MINは-2147483648で、その正の値+2147483648はintに収まりません。

abs(INT_MIN)、labs(LONG_MIN)、llabs(LLONG_MIN)は未定義動作です。

必要なら、より広い型に拡張してから計算するか、事前にチェックして別処理に分けると安全です。

整数の絶対値を求める

abs(int) の使い方

absint専用の絶対値関数です。

基本的な使い方は次のとおりです。

ただしINT_MINは未定義動作になるため、そのときは処理を分けます

C言語
// ファイル名: abs_int_example.c
#include <stdio.h>
#include <stdlib.h>  // abs
#include <limits.h>  // INT_MIN

int main(void) {
    int values[] = { -123, 0, 456, INT_MIN };
    size_t n = sizeof(values) / sizeof(values[0]);

    for (size_t i = 0; i < n; ++i) {
        int x = values[i];

        if (x == INT_MIN) {
            // INT_MINはabs(x)が未定義動作になる可能性がある
            // より広い型(long long)に拡張してから符号反転して安全に扱う
            long long widened = (long long)x;         // 拡張
            long long safe_abs = widened < 0 ? -widened : widened;
            printf("abs(INT_MIN) は未定義なのでスキップ。安全な幅での絶対値: %lld\n",
                   safe_abs);
        } else {
            // 通常の範囲なら安全にabsを使える
            int a = abs(x);
            printf("abs(%d) = %d\n", x, a);
        }
    }
    return 0;
}
実行結果
abs(-123) = 123
abs(0) = 0
abs(456) = 456
abs(INT_MIN) は未定義なのでスキップ。安全な幅での絶対値: 2147483648

labs(long) の使い方

labslong専用です。

環境によってlongのビット幅が異なる(Windowsでは多くの場合32bit、LinuxやmacOSでは多くの場合64bit)点に注意してください。

C言語
// ファイル名: labs_long_example.c
#include <stdio.h>
#include <stdlib.h>  // labs
#include <limits.h>  // LONG_MIN

int main(void) {
    long a = -1234567890L;
    long b = 0L;
    long c = 987654321L;

    printf("labs(%ld) = %ld\n", a, labs(a));
    printf("labs(%ld) = %ld\n", b, labs(b));
    printf("labs(%ld) = %ld\n", c, labs(c));

    // LONG_MINの場合は未定義動作になり得るので注意
    if (LONG_MIN < 0) {
        long m = LONG_MIN;
        // labs(m); // これは未定義動作になる可能性があるので避ける
        printf("LONG_MINの絶対値は同じlongに収まらないため、labs(LONG_MIN)は未定義です\n");
    }
    return 0;
}
実行結果
labs(-1234567890) = 1234567890
labs(0) = 0
labs(987654321) = 987654321
LONG_MINの絶対値は同じlongに収まらないため、labs(LONG_MIN)は未定義です

llabs(long long) の使い方

llabslong long専用です。

64bit整数の絶対値を取りたいときに使います。

C言語
// ファイル名: llabs_ll_example.c
#include <stdio.h>
#include <stdlib.h>  // llabs
#include <limits.h>  // LLONG_MIN

int main(void) {
    long long x = -9223372036854775807LL; // LLONG_MINは避ける
    long long y = 1234567890123LL;

    printf("llabs(%lld) = %lld\n", x, llabs(x));
    printf("llabs(%lld) = %lld\n", y, llabs(y));

    // LLONG_MINは未定義動作になり得る
    printf("LLONG_MINの絶対値はllabsでは未定義動作になります\n");
    return 0;
}
実行結果
llabs(-9223372036854775807) = 9223372036854775807
llabs(1234567890123) = 1234567890123
LLONG_MINの絶対値はllabsでは未定義動作になります

型に合わせて選ぶ

絶対値関数は「引数の型」と「戻り値の型」が一致するペアを選ぶのが基本です。

intabslonglabslong longllabsというように、無理なキャストを挟まずに素直に対応付けるとミスが減ります。

例えばlong longの値にabsを使うと、引数がintに変換され情報が失われる場合があるため危険です。

最小値に注意

INT_MIN・LONG_MIN・LLONG_MINの絶対値は同じ型では表現できないため、該当する可能性があるときは次のいずれかを行います。

  • 事前に最小値かどうかを判定して別処理にする。
  • より広い型に拡張してから絶対値を求め、広い型のまま扱う。

例として、intについて安全に処理するひな形を示します。

C言語
// INT_MINを安全に扱う例
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void) {
    int x = INT_MIN;

    if (x == INT_MIN) {
        // より広い型(long long)に拡張してから絶対値を求める
        long long ax = (long long)x;
        long long safe = ax < 0 ? -ax : ax;
        printf("INT_MINは未定義動作を避け、long longで扱う: %lld\n", safe);
    } else {
        printf("abs(%d) = %d\n", x, abs(x));
    }
    return 0;
}
実行結果
INT_MINは未定義動作を避け、long longで扱う: 2147483648
補足

より汎用に安全対策をしたい場合は<inttypes.h>intmax_timaxabsも検討できます。

浮動小数点の絶対値を求める

fabs(double) の使い方

小数(浮動小数点)の絶対値はfabsを使います。

負のゼロ(-0.0)はfabsで+0.0になります

また、fabs(INFINITY)INFINITYfabs(NAN)NANを返します。

C言語
// ファイル名: fabs_double_example.c
#include <stdio.h>
#include <math.h>     // fabs, INFINITY, NAN
#include <float.h>    // DBL_MAX (参考)
#include <fenv.h>     // 例外制御(今回は未使用)

int main(void) {
    double vals[] = { -3.14, 0.0, -0.0, INFINITY, -INFINITY, NAN };
    size_t n = sizeof(vals) / sizeof(vals[0]);

    for (size_t i = 0; i < n; ++i) {
        double x = vals[i];
        double ax = fabs(x);
        // %gでNaN/Infも表示しやすい
        printf("fabs(%g) = %g\n", x, ax);
    }
    return 0;
}
実行結果
fabs(-3.14) = 3.14
fabs(0) = 0
fabs(-0) = 0
fabs(inf) = inf
fabs(-inf) = inf
fabs(nan) = nan

表記(cst-code>infやnan)は処理系により少し異なることがあります。

小数にはfabsを使う

小数にabsを使うのは間違いです。

absint用なので、doubleを渡すと整数へ変換され、小数点以下が失われます。

C言語
// 誤用の例: absにdoubleを渡すと整数に丸められてしまう
#include <stdio.h>
#include <stdlib.h> // abs
#include <math.h>   // fabs

int main(void) {
    double d = -3.7;

    // 誤り: absはint用。-3.7は-3に変換される可能性が高い
    int wrong = abs(d);     // 実質的にabs(-3)と同等になりがち
    double right = fabs(d); // 正しい

    printf("誤用: abs(-3.7) -> %d (小数が失われる)\n", wrong);
    printf("正解: fabs(-3.7) -> %.1f\n", right);
    return 0;
}
実行結果
誤用: abs(-3.7) -> 3 (小数が失われる)
正解: fabs(-3.7) -> 3.7

小数にはfabsを使う、これが鉄則です。

floatならfabsf、long doubleならfabslもあります。

ヘッダとビルド

  • ヘッダ: fabs<math.h>にあります。
  • リンクオプション: Unix系(GCC/Clang)では数学ライブラリへのリンクが必要になることがあります。-lmを付けましょう。

ビルド例:

Shell
# GCC/Clang (Unix系): fabsを使う場合は -lm を付ける
gcc -std=c17 -Wall -Wextra fabs_double_example.c -lm -o fabs_example

# absのみなら -lm は不要
gcc -std=c17 -Wall -Wextra abs_int_example.c -o abs_example

# WindowsのMSVCは通常 -lm 不要
cl /std:c17 /W4 fabs_double_example.c

abs・labs・llabs・fabsの使い分けガイド

型で選ぶ早見

「変数の型 = 使う関数」の対応が基本ルールです。

変数の型関数戻り値の型ヘッダ
intabsint<stdlib.h>
longlabslong<stdlib.h>
long longllabslong long<stdlib.h>
doublefabsdouble<math.h>
補足

floatにはfabsf、long doubleにはfabslが対応します。

ヘッダの違いで迷わない

  • 整数の絶対値(abs/labs/llabs)は<stdlib.h>
  • 浮動小数点の絶対値(fabs)は<math.h>
  • 数学関数を使うときは、GCC/Clangでは-lmが必要なことがある点に注意。

よくあるミス

  • doubleにabsを使ってしまい、小数部分が落ちる。小数はfabs
  • 最小値(INT_MIN/LONG_MIN/LLONG_MIN)に対して絶対値を取り、未定義動作を起こす。事前チェックか、より広い型へ拡張してから処理。
  • #includeを間違える。整数は<stdlib.h>、小数は<math.h>
  • GCC/Clangで-lmを付け忘れ、リンクエラー。数学関数を使うときは忘れずに。
  • 自作マクロで絶対値を実装し、副作用やオーバーフローを見落とす。標準関数の利用が安全。

まとめ

絶対値は「型によって関数が異なる」ことが最大のポイントです。

整数にはabs/labs/llabs、小数にはfabsを使い分け、ヘッダは<stdlib.h><math.h>を間違えないことが大切です。

さらに、最小値(INT_MINなど)への絶対値は未定義動作になるため、より広い型へ拡張するか事前チェックで安全に回避しましょう。

この記事のサンプルを土台に、用途と型に合った正しい絶対値の取り方を身につけてください。

C言語 標準ライブラリの活用

この記事を書いた人
エーテリア編集部
エーテリア編集部

プログラミングの基礎をしっかり学びたい方向けに、C言語の基本文法から解説しています。ポインタやメモリ管理も少しずつ理解できるよう工夫しています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!