Last Update 2023/03/23
数値を格納・処理する型が取り扱い可能な範囲に関するテスト
概要
現在の環境における整数型の格納範囲を定義するマクロの値を出力
現在の環境における浮動小数点型の格納範囲を定義するマクロの値を出力
その1
現在の環境における整数型の格納範囲を定義するマクロの値を出力
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void)
{
printf("********** 現在の環境における整数型の格納範囲を定義するマクロ **********\n\n");
/* 各範囲値マクロに関するコメントは「limits.h(glibc-2.36)」を参照 */
printf("任意のロケールにおけるマルチバイト文字の最大長\n");
printf("\tMB_LEN_MAX = %d\n\n", MB_LEN_MAX);
printf("char型のビット数\n");
printf("\tCHAR_BIT = %d\n\n", CHAR_BIT);
printf("signed char型の最小値\n");
printf("\tSCHAR_MIN = %d\n", SCHAR_MIN);
printf("signed char型の最大値\n");
printf("\tSCHAR_MAX = %d\n", SCHAR_MAX);
printf("signed char型のバイト数\n");
printf("\tsizeof(signed char) = %ld\n\n", sizeof(signed char));
printf("unsigned char型の最大値\n");
printf("\tUCHAR_MAX = %d\n", UCHAR_MAX);
printf("unsigned char型のバイト数\n");
printf("\tsizeof(unsigned char) = %ld\n\n", sizeof(unsigned char));
printf("short int型の最小値\n");
printf("\tSHRT_MIN = %ld\n", (long)SHRT_MIN);
printf("short int型の最大値\n");
printf("\tSHRT_MAX = %ld\n", (long)SHRT_MAX);
printf("unsigned char型のバイト数\n");
printf("\tsizeof(short int) = %ld\n\n", sizeof(short int));
printf("unsigned short int型の最大値\n");
printf("\tUSHRT_MAX = %ld\n", (long)USHRT_MAX);
printf("unsigned short int型のバイト数\n");
printf("\tsizeof(unsigned short int) = %ld\n\n", sizeof(unsigned short int));
printf("signed int型の最小値\n");
printf("\tINT_MIN = %ld\n", (long)INT_MIN);
printf("signed int型の最大値\n");
printf("\tINT_MAX = %ld\n", (long)INT_MAX);
printf("signed int型のバイト数\n");
printf("\tsizeof(signed int) = %ld\n\n", sizeof(signed int));
printf("unsigned int型の最大値\n");
printf("\tUINT_MAX = %ld\n", (long)UINT_MAX);
printf("unsigned int型のバイト数\n");
printf("\tsizeof(unsigned int) = %ld\n\n", sizeof(unsigned int));
printf("signed long int型の最小値\n");
printf("\tLONG_MIN = %lld\n", (long long)LONG_MIN);
printf("signed long int型の最大値\n");
printf("\tLONG_MAX = %lld\n", (long long)LONG_MAX);
printf("signed long int型のバイト数\n");
printf("\tsizeof(signed long int) = %ld\n\n", sizeof(signed long int));
printf("unsigned long int型の最大値\n");
printf("\tULONG_MAX = %llu\n", (unsigned long long)ULONG_MAX);
printf("unsigned long int型のバイト数\n");
printf("\tsizeof(unsigned long int) = %ld\n\n", sizeof(unsigned long int));
printf("signed long long int型の最小値\n");
printf("\tLLONG_MIN = %lld\n", (long long)LLONG_MIN);
printf("signed long long int型の最大値\n");
printf("\tLLONG_MAX = %lld\n", (long long)LLONG_MAX);
printf("signed long long int型のバイト数\n");
printf("\tsizeof(signed long long int) = %ld\n\n", sizeof(signed long long int));
printf("unsigned long long int型の最大値\n");
printf("\tULLONG_MAX = %llu\n", (unsigned long long)ULLONG_MAX);
printf("unsigned long long int型のバイト数\n");
printf("\tsizeof(unsigned long long int) = %ld\n\n", sizeof(unsigned long long int));
return EXIT_SUCCESS;
}
実行結果
$ ./a.out
********** 現在の環境における整数型の格納範囲を定義するマクロ **********
任意のロケールにおけるマルチバイト文字の最大長
MB_LEN_MAX = 16
char型のビット数
CHAR_BIT = 8
signed char型の最小値
SCHAR_MIN = -128
signed char型の最大値
SCHAR_MAX = 127
signed char型のバイト数
sizeof(signed char) = 1
unsigned char型の最大値
UCHAR_MAX = 255
unsigned char型のバイト数
sizeof(unsigned char) = 1
short int型の最小値
SHRT_MIN = -32768
short int型の最大値
SHRT_MAX = 32767
unsigned char型のバイト数
sizeof(short int) = 2
unsigned short int型の最大値
USHRT_MAX = 65535
unsigned short int型のバイト数
sizeof(unsigned short int) = 2
signed int型の最小値
INT_MIN = -2147483648
signed int型の最大値
INT_MAX = 2147483647
signed int型のバイト数
sizeof(signed int) = 4
unsigned int型の最大値
UINT_MAX = 4294967295
unsigned int型のバイト数
sizeof(unsigned int) = 4
signed long int型の最小値
LONG_MIN = -9223372036854775808
signed long int型の最大値
LONG_MAX = 9223372036854775807
signed long int型のバイト数
sizeof(signed long int) = 8
unsigned long int型の最大値
ULONG_MAX = 18446744073709551615
unsigned long int型のバイト数
sizeof(unsigned long int) = 8
signed long long int型の最小値
LLONG_MIN = -9223372036854775808
signed long long int型の最大値
LLONG_MAX = 9223372036854775807
signed long long int型のバイト数
sizeof(signed long long int) = 8
unsigned long long int型の最大値
ULLONG_MAX = 18446744073709551615
unsigned long long int型のバイト数
sizeof(unsigned long long int) = 8
その2
現在の環境における浮動小数点型の格納範囲を定義するマクロの値を出力
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
int main(void)
{
printf("********** 現在の環境における浮動小数点型の格納範囲を定義するマクロ **********\n");
/* 各範囲値マクロに関するコメントは「float.h(glibc-2.36)」を参照 */
printf("指数表現の基数\n");
printf(" FLT_RADIX = %d\n\n", FLT_RADIX);
printf("仮数部の基数FLT_RADIX(%d)の桁数\n", FLT_RADIX);
printf(" float FLT_MANT_DIG = %d\n", FLT_MANT_DIG);
printf(" double DBL_MANT_DIG = %d\n", DBL_MANT_DIG);
printf(" long double LDBL_MANT_DIG = %d\n\n", LDBL_MANT_DIG);
printf("10進数での精度\n");
printf(" float FLT_DIG = %d ", FLT_DIG);
printf(" floor((%d - 1) * log10(%d)) = %d\n", FLT_MANT_DIG, FLT_RADIX,
(int)floor((FLT_MANT_DIG - 1) * log10(FLT_RADIX)));
printf(" double DBL_DIG = %d ", DBL_DIG);
printf(" floor((%d - 1) * log10(%d)) = %d\n", DBL_MANT_DIG, FLT_RADIX,
(int)floor((DBL_MANT_DIG - 1) * log10(FLT_RADIX)));
printf(" long double LDBL_DIG = %d ", LDBL_DIG);
printf(" floor((%d - 1) * log10(%d)) = %d\n\n", LDBL_MANT_DIG, FLT_RADIX,
(int)floor((LDBL_MANT_DIG - 1) * log10(FLT_RADIX)));
printf("FLT_RADIX**(x-1)が正規化された浮動小数点数であるような最小の整数 X\n");
printf(" float FLT_MIN_EXP = %d\n", FLT_MIN_EXP);
printf(" double DBL_MIN_EXP = %d\n", DBL_MIN_EXP);
printf(" long double LDBL_MIN_EXP = %d\n\n", LDBL_MIN_EXP);
printf("10をべき乗した値が正規化された浮動小数点数の範囲にあるような最小の負の整数\n");
printf(" float FLT_MIN_10_EXP = %d ", FLT_MIN_10_EXP);
printf(" ceil(log10(%d) * (%d - 1)) = %d\n", FLT_RADIX, FLT_MIN_EXP,
(int)ceil(log10(FLT_RADIX) * (FLT_MIN_EXP - 1)));
printf(" double DBL_MIN_10_EXP = %d ", DBL_MIN_10_EXP);
printf(" ceil(log10(%d) * (%d - 1)) = %d\n", FLT_RADIX, DBL_MIN_EXP,
(int)ceil(log10(FLT_RADIX) * (DBL_MIN_EXP - 1)));
printf(" long double LDBL_MIN_10_EXP = %d ", LDBL_MIN_10_EXP);
printf(" ceil(log10(%d) * (%d - 1)) = %d\n\n", FLT_RADIX, LDBL_MIN_EXP,
(int)ceil(log10(FLT_RADIX) * (LDBL_MIN_EXP - 1)));
printf("FLT_RADIX**(x-1)が表現可能な浮動小数点数であるような最大の整数 X\n");
printf(" float FLT_MAX_EXP = %d\n", FLT_MAX_EXP);
printf(" double DBL_MAX_EXP = %d\n", DBL_MAX_EXP);
printf(" long double LDBL_MAX_EXP = %d\n\n", LDBL_MAX_EXP);
printf("10をべき乗した値が表現可能な有限浮動小数点数の範囲にあるような最大の正の整数\n");
printf(" float FLT_MAX_10_EXP = %d ", FLT_MAX_10_EXP);
printf(" floor(log10((1 - %d**-%d) * %d**%d)) = %d\n", FLT_RADIX, FLT_MANT_DIG, FLT_RADIX, FLT_MAX_EXP,
(int)floor(log10((1 - pow(FLT_RADIX, - FLT_MANT_DIG)) * pow(FLT_RADIX, FLT_MAX_EXP))));
printf(" double DBL_MAX_10_EXP = %d ", DBL_MAX_10_EXP);
printf(" floor(log10((1 - %d**-%d) * %d**%d)) = %d\n", FLT_RADIX, DBL_MANT_DIG, FLT_RADIX, DBL_MAX_EXP,
(int)floor(log10l((1 - powl(FLT_RADIX, - DBL_MANT_DIG)) * powl(FLT_RADIX, DBL_MAX_EXP))));
printf(" long double LDBL_MAX_10_EXP = %d ", LDBL_MAX_10_EXP);
printf(" floor(log10((1 - %d**-%d) * %d**%d)) = %d\n\n", FLT_RADIX, LDBL_MANT_DIG, FLT_RADIX, LDBL_MAX_EXP,
(int)floor(log10l((1 - powl(FLT_RADIX, - LDBL_MANT_DIG)) * powl(FLT_RADIX, LDBL_MAX_EXP - 0.000001))));
/* long doubleの範囲内に収めるため便宜的にLDBL_MAX_EXPから0.000001を減算 */
printf("最小正規化正浮動小数点数\n");
printf(" float FLT_MIN = %e ", FLT_MIN);
printf(" %d**(%d - 1) = %e\n", FLT_RADIX, FLT_MIN_EXP,
pow(FLT_RADIX, (FLT_MIN_EXP - 1)));
printf(" double DBL_MIN = %e ", DBL_MIN);
printf(" %d**(%d - 1) = %Le\n", FLT_RADIX, DBL_MIN_EXP,
powl(FLT_RADIX, (DBL_MIN_EXP - 1)));
printf(" long double LDBL_MIN = %Le ", LDBL_MIN);
printf(" %d**(%d - 1) = %Le\n\n", FLT_RADIX, LDBL_MIN_EXP,
powl(FLT_RADIX, (LDBL_MIN_EXP - 1)));
printf("最大表現可能有限浮動小数点数\n");
printf(" float FLT_MAX = %e ", FLT_MAX);
printf(" (1 - %d**-%d) * %d**%d = %e\n", FLT_RADIX, FLT_MANT_DIG, FLT_RADIX, FLT_MAX_EXP,
(1 - pow(FLT_RADIX, - FLT_MANT_DIG)) * pow(FLT_RADIX, FLT_MAX_EXP));
printf(" double DBL_MAX = %e ", DBL_MAX);
printf(" (1 - %d**-%d) * %d**%d = %Le\n", FLT_RADIX, DBL_MANT_DIG, FLT_RADIX, DBL_MAX_EXP,
(1 - powl(FLT_RADIX, - DBL_MANT_DIG)) * powl(FLT_RADIX, DBL_MAX_EXP));
printf(" long double LDBL_MAX = %Le ", LDBL_MAX);
printf(" (1 - %d**-%d) * %d**%d = %Le\n", FLT_RADIX, LDBL_MANT_DIG, FLT_RADIX, LDBL_MAX_EXP,
(1 - powl(FLT_RADIX, - LDBL_MANT_DIG)) * powl(FLT_RADIX, LDBL_MAX_EXP - 0.000001));
/* long doubleの範囲内に収めるため便宜的にLDBL_MAX_EXPから0.000001を減算 */
printf("1と、浮動小数点数で表現可能な1より大きい最小値との差\n");
printf(" float FLT_EPSILON = %e ", FLT_EPSILON);
printf(" %d**(1- %d) = %e\n", FLT_RADIX, FLT_MANT_DIG,
pow(FLT_RADIX, (1 - FLT_MANT_DIG)));
printf(" double DBL_EPSILON = %e ", DBL_EPSILON);
printf(" %d**(1- %d) = %Le\n", FLT_RADIX, DBL_MANT_DIG,
powl(FLT_RADIX, (1 - DBL_MANT_DIG)));
printf(" long double LDBL_EPSILON = %Le ", LDBL_EPSILON);
printf(" %d**(1- %d) = %Le\n\n", FLT_RADIX, LDBL_MANT_DIG,
powl(FLT_RADIX, (1 - LDBL_MANT_DIG)));
printf("加算の丸めモード\n");
printf(" FLT_ROUNDS = %d\n", FLT_ROUNDS);
printf(" 1 : 最も近くへ\n\n", FLT_ROUNDS);
/* -1 : 未定
0 : 0へ
1 : 最も近くへ
2 : 次に大きい値へ
3 : 次に小さい値へ
*/
printf("浮動小数点式の評価方法\n");
#ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
printf(" __STDC_WANT_IEC_60559_TYPES_EXT__ 定義済み\n");
#else
printf(" __STDC_WANT_IEC_60559_TYPES_EXT__ 定義なし\n");
#endif
printf(" FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
printf(" すべての演算と定数を,その型の範囲と精度だけで評価\n\n");
/*
-1 不定
0 すべての演算と定数を,その型の範囲と精度だけで評価
1 float型とdouble型の演算と定数をdouble型の範囲と精度で評価し、
long double型の演算と定数をlong double型の範囲と精度で評価
2 すべての演算と定数を long double 型の範囲と精度で評価
*/
printf("サポートされている最大浮動小数点型を、値を変えることなく10進数とFLT_RADIX進数表記間変換可能な10進桁数\n");
printf(" DECIMAL_DIG = %d ", DECIMAL_DIG);
printf(" ceil(1 + %d * log10(%d)) = %d\n\n", LDBL_MANT_DIG, FLT_RADIX,
(int)ceil(1 + LDBL_MANT_DIG * log10(FLT_RADIX)));
return EXIT_SUCCESS;
}
実行結果
$ ./a.out
********** 現在の環境における浮動小数点型の格納範囲を定義するマクロ **********
指数表現の基数
FLT_RADIX = 2
仮数部の基数FLT_RADIX(2)の桁数
float FLT_MANT_DIG = 24
double DBL_MANT_DIG = 53
long double LDBL_MANT_DIG = 64
10進数での精度
float FLT_DIG = 6 floor((24 - 1) * log10(2)) = 6
double DBL_DIG = 15 floor((53 - 1) * log10(2)) = 15
long double LDBL_DIG = 18 floor((64 - 1) * log10(2)) = 18
FLT_RADIX**(x-1)が正規化された浮動小数点数であるような最小の整数 X
float FLT_MIN_EXP = -125
double DBL_MIN_EXP = -1021
long double LDBL_MIN_EXP = -16381
10をべき乗した値が正規化された浮動小数点数の範囲にあるような最小の負の整数
float FLT_MIN_10_EXP = -37 ceil(log10(2) * (-125 - 1)) = -37
double DBL_MIN_10_EXP = -307 ceil(log10(2) * (-1021 - 1)) = -307
long double LDBL_MIN_10_EXP = -4931 ceil(log10(2) * (-16381 - 1)) = -4931
FLT_RADIX**(x-1)が表現可能な浮動小数点数であるような最大の整数 X
float FLT_MAX_EXP = 128
double DBL_MAX_EXP = 1024
long double LDBL_MAX_EXP = 16384
10をべき乗した値が表現可能な有限浮動小数点数の範囲にあるような最大の正の整数
float FLT_MAX_10_EXP = 38 floor(log10((1 - 2**-24) * 2**128)) = 38
double DBL_MAX_10_EXP = 308 floor(log10((1 - 2**-53) * 2**1024)) = 308
long double LDBL_MAX_10_EXP = 4932 floor(log10((1 - 2**-64) * 2**16384)) = 4932
最小正規化正浮動小数点数
float FLT_MIN = 1.175494e-38 2**(-125 - 1) = 1.175494e-38
double DBL_MIN = 2.225074e-308 2**(-1021 - 1) = 2.225074e-308
long double LDBL_MIN = 3.362103e-4932 2**(-16381 - 1) = 3.362103e-4932
最大表現可能有限浮動小数点数
float FLT_MAX = 3.402823e+38 (1 - 2**-24) * 2**128 = 3.402823e+38
double DBL_MAX = 1.797693e+308 (1 - 2**-53) * 2**1024 = 1.797693e+308
long double LDBL_MAX = 1.189731e+4932 (1 - 2**-64) * 2**16384 = 1.189731e+4932
1と、浮動小数点数で表現可能な1より大きい最小値との差
float FLT_EPSILON = 1.192093e-07 2**(1- 24) = 1.192093e-07
double DBL_EPSILON = 2.220446e-16 2**(1- 53) = 2.220446e-16
long double LDBL_EPSILON = 1.084202e-19 2**(1- 64) = 1.084202e-19
加算の丸めモード
FLT_ROUNDS = 1
1 : 最も近くへ
浮動小数点式の評価方法
__STDC_WANT_IEC_60559_TYPES_EXT__ 定義なし
FLT_EVAL_METHOD = 0
すべての演算と定数を,その型の範囲と精度だけで評価
サポートされている最大浮動小数点型を、値を変えることなく10進数とFLT_RADIX進数表記間変換可能な10進桁数
DECIMAL_DIG = 21 ceil(1 + 64 * log10(2)) = 21
実行環境
GNU bash, version 5.1.16
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。