こんにちは、ナナです。
「絶対値」とは正負という符号の概念がない、大きさのみを表す数値のことです。
例えば「-10」という数値の絶対値は「10」となります。
プログラムを行う中で「マイナスの符号を外したいな」という場面があります。そんな時にC言語ではどのようにプログラミングをするかを学びましょう。
絶対値の取得は、標準ライブラリ関数を使うのが一般的です。ですが、関数マクロを定義すると、もっと汎用的に絶対値を取得できるようになります。
本記事では次の悩みを解消する内容となっています。
では、まずは標準ライブラリ関数を使った絶対値から学んでいきましょう。
絶対値を取得するための標準ライブラリ関数
まずは、一番基本となる絶対値を求める標準ライブラリ関数を紹介します。
整数型の絶対値の取得関数
#include <stdlib.h>
int abs(int num);
long labs(long num);
long long llabs(long long num);
浮動小数点型の絶対値の取得関数
#include <math.h>
float fabsf(float num);
double fabs(double num);
絶対値は英語で「absolute value」と表現されるため「abs」という名が付いた関数になります。
abs関数、labs関数、llabs関数の仕様
整数型の数値に対する絶対値を取得するための関数です。戻り値で絶対値を取得します。
includeファイル | stdlib.h |
関数仕様 | int abs(int num); long labs(long num); long long llabs(long long num); |
引数 | num:絶対値を取得したい元の数値 |
戻り値 | 絶対値の取得結果が返却される。 |
特記事項 | データ型により利用する関数を変更する必要がある。 char型とshort型の場合はabs関数を使用する。 |
fabsf関数、fabs関数の仕様
浮動小数点型の数値に対する絶対値を取得するための関数です。戻り値で絶対値を取得します。
includeファイル | math.h |
関数仕様 | float fabsf(float num); double fabs(double num); |
引数 | num:絶対値を取得したい元の数値 |
戻り値 | 絶対値の取得結果が返却される。 |
特記事項 | 整数型とはインクルードするファイルが異なることに注意。 |
整数型と浮動小数点型のタイプの違いによりインクルードするファイルが異なることに注意です。
標準ライブラリ関数はデータ型によって関数を切り替える必要があります。使用する際には、注意しましょう。
絶対値を取得するabs関数を使ったサンプルコードと実行結果
整数型のabs関数を使ったサンプルコードになります。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// 整数型の変数定義
int num1 = -100;
long num2 = -200;
long long num3 = -300;
// 変換前の値の表示
printf("変換前\n");
printf("%d\n", num1);
printf("%ld\n", num2);
printf("%lld\n", num3);
// 絶対値への変換
num1 = abs(num1);
num2 = labs(num2);
num3 = llabs(num3);
// 変換後の値の表示
printf("\n変換後\n");
printf("%d\n" , num1);
printf("%ld\n" , num2);
printf("%lld\n", num3);
return 0;
}
変換前
-100
-200
-300
変換後
100
200
300
浮動小数点型のabs関数のサンプルコードです。
#include <stdio.h>
#include <math.h>
int main(void)
{
// 浮動小数点型の変数定義
float num1 = -10.5;
double num2 = -20.5;
// 変換前の値の表示
printf("変換前\n");
printf("%f\n", num1);
printf("%lf\n", num2);
// 絶対値への変換
num1 = fabsf(num1);
num2 = fabs(num2);
// 変換後の値の表示
printf("\n変換後\n");
printf("%f\n" , num1);
printf("%lf\n" , num2);
return 0;
}
変換前
-10.500000
-20.500000
変換後
10.500000
20.500000
標準ライブラリ関数の基礎を知った上で、関数マクロのメリットを学んでいきますよ。
絶対値を取得する関数がたくさんある理由
標準ライブラリ関数には、絶対値の取得関数がたくさんありますね。これはC言語がデータ型に厳しい言語であることが原因です。
C言語ではデータ型が異なると、データ型に応じて関数を別で定義せねばなりません。キャストで許容できる範囲ならよいのですが、基本は別で定義することになります。
abs系関数は種類がたくさんあることで、どれを使うか選定する手順に使いづらさを感じてしまうところが残念な部分です。
関数がたくさんあるのが、使いづらさとも言えます。このような機能は関数マクロの方が汎用性が高くなります。次は関数マクロの絶対値取得方法を紹介しましょう。
絶対値を取得するための関数マクロ定義と使用例
自分で定義する必要がありますが、関数マクロを利用した絶対値の取得方法があります。
関数マクロのメリットは、データ型の依存性をなくすことができることです。データ型に依存せず一律で変換ができます。
では、定義方法と使用例を示します。
関数マクロを使った定義方法
#define ABS_FUNC(x) ((x) < 0 ? -(x) : (x))
関数マクロ名は、もちろん他の名前でも問題ありません。
対象の数値を3項演算子を使って符号を取り除いています。「x」が負値の場合はマイナス記号を付けることで打ち消しあいます。
関数マクロを使った場合のメリットとは
関数マクロを使う場合は、「x」で指定した変数や定数が置換されて展開されます。
そのため、指定した変数や定数値のデータ型がそのまま演算に利用されます。つまり、「x」がどのような変数のデータ型でも、演算の型を統一することができるのです。
関数マクロについて詳しく知りたい方は、マクロ定義の記事を参考にしてください。
》参考:define マクロ【数値に名前を付ける意味とメリット】
関数マクロを使ったサンプルコード
#include <stdio.h>
// 絶対値を取得する関数マクロ定義
#define ABS_FUNC(x) ((x) < 0 ? -(x) : (x))
int main(void)
{
int num1 = -100;
long num2 = -200;
long long num3 = -300;
float num4 = -10.5;
double num5 = -20.5;
// 絶対値への変換
num1 = ABS_FUNC(num1);
num2 = ABS_FUNC(num2);
num3 = ABS_FUNC(num3);
num4 = ABS_FUNC(num4);
num5 = ABS_FUNC(num5);
// 変換後の値の表示
printf("%d\n" , num1);
printf("%ld\n" , num2);
printf("%lld\n", num3);
printf("%f\n" , num4);
printf("%lf\n" , num5);
return 0;
}
100
200
300
10.500000
20.500000
このように関数マクロを使った場合は、対象の変数がなんであっても、統一した処理で絶対値を得ることができます。
自分で定義しなければならないデメリットはありますが、データ型の依存性を排除できるメリットが関数マクロにはあります。