名前空間
変種
操作

std::ilogb, std::ilogbf, std::ilogbl

From cppreference.com
< cpp‎ | numeric‎ | math
 
 
 
 
ヘッダー <cmath> で定義
(1)
int ilogb ( float num );

int ilogb ( double num );

int ilogb ( long 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)
1-3)浮動小数点引数 num から、正規化されていない指数(unbiased exponent)の値を抽出し、符号付き整数値として返します。ライブラリは、パラメータ num の型として、すべての cv 修飾されていない浮動小数点型に対する std::ilogb のオーバーロードを提供します。(since C++23)
4) INT_MIN または -INT_MAX のいずれかの値を持つ整数定数式に展開されます。
5) INT_MIN または +INT_MAX のいずれかの値を持つ整数定数式に展開されます。
A) すべての整数型に対する追加のオーバーロードが提供されます。これらは double として扱われます。

形式的には、非ゼロ num に対して、正規化されていない指数は logr|num| の整数部分を符号付き整数値として表したものです。ここで rstd::numeric_limits<T>::radix であり、Tnum の浮動小数点型です。

目次

[編集] パラメータ

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) をサポートしている場合、

[編集] 注記

num がゼロ、無限大、または NaN でない場合、返される値は static_cast<int>(std::logb(num)) と完全に等価です。

POSIX はnum がゼロ、無限大、NaN である場合、または正しい結果が int の範囲外である場合にドメインエラーが発生することを要求しています。

POSIX はまた、XSI 準拠のシステムでは、正しい結果が INT_MAX より大きい場合に返される値が INT_MAX であり、正しい結果が INT_MIN より小さい場合に返される値が INT_MIN であることを要求しています。

正しい結果は、すべての既知の実装で int で表現可能です。オーバーフローが発生するためには、INT_MAXLDBL_MAX_EXP * std::log2(FLT_RADIX) より小さいか、INT_MINLDBL_MIN_EXP - LDBL_MANT_DIG) * std::log2(FLT_RADIX) より大きい必要があります。

std::ilogb によって返される指数の値は、正規化要件の違いにより、std::frexp によって返される指数よりも常に1小さくなります。std::ilogb によって返される指数 e の場合、|num*r-e
|
1r の間(通常は 12 の間)ですが、std::frexp によって返される指数 e の場合、|num*2-e
|
0.51 の間です。

追加のオーバーロードは、(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 のべき乗を掛ける
(関数) [編集]
English 日本語 中文(简体) 中文(繁體)