std::ilogb, std::ilogbf, std::ilogbl
| ヘッダー <cmath> で定義 |
||
| (1) | ||
int ilogb ( float num ); int ilogb ( double num ); |
(C++11以降) (C++23まで) |
|
| constexpr int ilogb( /* floating-point-type */ num ); |
(C++23から) | |
| int ilogbf( float num ); |
(2) | (C++11以降) (C++23 以降 constexpr) |
| int ilogbl( long double num ); |
(3) | (C++11以降) (C++23 以降 constexpr) |
| #define FP_ILOGB0 /* 実装定義 */ |
(4) | (C++11以降) |
| #define FP_ILOGBNAN /* 実装定義 */ |
(5) | (C++11以降) |
| ヘッダー <cmath> で定義 |
||
| template< class Integer > int ilogb ( Integer num ); |
(A) | (C++11以降) (C++23 以降 constexpr) |
std::ilogb のオーバーロードを提供します。(since C++23)形式的には、非ゼロ num に対して、正規化されていない指数は logr|num| の整数部分を符号付き整数値として表したものです。ここで r は std::numeric_limits<T>::radix であり、T は num の浮動小数点型です。
目次 |
[編集] パラメータ
| num | - | 浮動小数点数または整数値 |
[編集] 戻り値
エラーが発生しない場合、num の正規化されていない指数が符号付き int 値として返されます。
num がゼロの場合、FP_ILOGB0 が返されます。
num が無限大の場合、INT_MAX が返されます。
num が NaN の場合、FP_ILOGBNAN が返されます。
正しい結果が INT_MAX より大きいか、INT_MIN より小さい場合、戻り値は未定義です。
[編集] エラー処理
エラーは math_errhandling で指定された通りに報告される。
num がゼロ、無限大、または NaN の場合、ドメインエラーまたは範囲エラーが発生する可能性があります。
正しい結果が INT_MAX より大きいか、INT_MIN より小さい場合、ドメインエラーまたは範囲エラーが発生する可能性があります。
実装がIEEE浮動小数点算術 (IEC 60559) をサポートしている場合、
- 正しい結果が INT_MAX より大きいか、INT_MIN より小さい場合、FE_INVALID が発生します。
- num が ±0、±∞、または NaN の場合、FE_INVALID が発生します。
- それ以外の場合、結果は正確であり(FE_INEXACT は発生しません)、現在の丸めモードは無視されます。
[編集] 注記
num がゼロ、無限大、または NaN でない場合、返される値は static_cast<int>(std::logb(num)) と完全に等価です。
POSIX は、num がゼロ、無限大、NaN である場合、または正しい結果が int の範囲外である場合にドメインエラーが発生することを要求しています。
POSIX はまた、XSI 準拠のシステムでは、正しい結果が INT_MAX より大きい場合に返される値が INT_MAX であり、正しい結果が INT_MIN より小さい場合に返される値が INT_MIN であることを要求しています。
正しい結果は、すべての既知の実装で int で表現可能です。オーバーフローが発生するためには、INT_MAX が LDBL_MAX_EXP * std::log2(FLT_RADIX) より小さいか、INT_MIN が LDBL_MIN_EXP - LDBL_MANT_DIG) * std::log2(FLT_RADIX) より大きい必要があります。
std::ilogb によって返される指数の値は、正規化要件の違いにより、std::frexp によって返される指数よりも常に1小さくなります。std::ilogb によって返される指数 e の場合、|num*r-e
| は 1 と r の間(通常は 1 と 2 の間)ですが、std::frexp によって返される指数 e の場合、|num*2-e
| は 0.5 と 1 の間です。
追加のオーバーロードは、(A) とまったく同じように提供される必要はありません。整数型の引数 num に対して、std::ilogb(num) が std::ilogb(static_cast<double>(num)) と同じ効果を持つことを保証するのに十分であればよいのです。
[編集] 例
異なる浮動小数点分解関数を比較します。
#include <cfenv> #include <cmath> #include <iostream> #include <limits> // #pragma STDC FENV_ACCESS ON int main() { double f = 123.45; std::cout << "Given the number " << f << " or " << std::hexfloat << f << std::defaultfloat << " in hex,\n"; double f3; double f2 = std::modf(f, &f3); std::cout << "modf() makes " << f3 << " + " << f2 << '\n'; int i; f2 = std::frexp(f, &i); std::cout << "frexp() makes " << f2 << " * 2^" << i << '\n'; i = std::ilogb(f); std::cout << "logb()/ilogb() make " << f / std::scalbn(1.0, i) << " * " << std::numeric_limits<double>::radix << "^" << std::ilogb(f) << '\n'; // error handling std::feclearexcept(FE_ALL_EXCEPT); std::cout << "ilogb(0) = " << std::ilogb(0) << '\n'; if (std::fetestexcept(FE_INVALID)) std::cout << " FE_INVALID raised\n"; }
実行結果の例
Given the number 123.45 or 0x1.edccccccccccdp+6 in hex,
modf() makes 123 + 0.45
frexp() makes 0.964453 * 2^7
logb()/ilogb() make 1.92891 * 2^6
ilogb(0) = -2147483648
FE_INVALID raised[編集] 関連項目
| (C++11)(C++11) |
数値を仮数部と2を底とする指数部に分解する (関数) |
| (C++11)(C++11)(C++11) |
数値の指数部を抽出する (関数) |
| (C++11)(C++11)(C++11)(C++11)(C++11)(C++11) |
数値に FLT_RADIX のべき乗を掛ける (関数) |
| C のドキュメント (ilogb)
| |