std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl
| ヘッダー <cmath> で定義 |
||
| (1) | ||
float nextafter ( float from, float to ); double nextafter ( double from, double to ); |
(C++11以降) (C++23まで) |
|
| constexpr /* floating-point-type */ nextafter ( /* 浮動小数点型 */ from, |
(C++23から) | |
| float nextafterf( float from, float to ); |
(2) | (C++11以降) (C++23 以降 constexpr) |
| long double nextafterl( long double from, long double to ); |
(3) | (C++11以降) (C++23 以降 constexpr) |
| (4) | ||
float nexttoward ( float from, long double to ); double nexttoward ( double from, long double to ); |
(C++11以降) (C++23まで) |
|
| constexpr /* floating-point-type */ nexttoward ( /* 浮動小数点型 */ from, |
(C++23から) | |
| float nexttowardf( float from, long double to ); |
(5) | (C++11以降) (C++23 以降 constexpr) |
| long double nexttowardl( long double from, long double to ); |
(6) | (C++11以降) (C++23 以降 constexpr) |
| ヘッダー <cmath> で定義 |
||
| template< class Arithmetic1, class Arithmetic2 > /* 共通浮動小数点型 */ |
(A) | (C++11以降) (C++23 以降 constexpr) |
| template< class Integer > double nexttoward( Integer from, long double to ); |
(B) | (C++11以降) (C++23 以降 constexpr) |
from から to の方向における、次に表現可能な値を返します。
std::nextafter のオーバーロードを提供します。(since C++23)|
ライブラリは、from パラメータの型として、すべての cv 修飾されていない浮動小数点型に対する |
(C++23から) |
std::nextafter オーバーロードが提供されます。std::nexttoward オーバーロードが提供されます。これらの整数型は double として扱われます。目次 |
[編集] Parameters
| from, to | - | 浮動小数点または整数値 |
[編集] Return value
エラーが発生しなかった場合、 from から to の方向における、次に表現可能な値を返します。 from が to と等しい場合、 to を返します。
オーバーフローによる範囲エラーが発生した場合、 ±HUGE_VAL、 ±HUGE_VALF、または ±HUGE_VALL を返します( from と同じ符号を持ちます)。
アンダーフローによる範囲エラーが発生した場合、正しい結果が返されます。
[編集] Error handling
エラーは math_errhandling で指定された通りに報告される。
実装がIEEE浮動小数点算術 (IEC 60559) をサポートしている場合、
- from が有限値であり、期待される結果が無限大である場合、 FE_INEXACT および FE_OVERFLOW を発生させます。
- from が to と等しくなく、結果がサブナラマル値またはゼロである場合、 FE_INEXACT および FE_UNDERFLOW を発生させます。
- いずれの場合も、返される値は現在の丸めモードに依存しません。
- from または to のいずれかが NaN の場合、 NaN が返されます。
[編集] Notes
POSIX は、オーバーフローとアンダーフローの条件を範囲エラー( errno が設定される場合がある)として指定しています。
IEC 60559 は、 from == to の場合、 from を返すことを推奨しています。これらの関数は代わりに to を返すため、ゼロ周辺の動作が一貫します: std::nextafter(-0.0, +0.0) は +0.0 を返し、 std::nextafter(+0.0, -0.0) は -0.0 を返します。
std::nextafter は通常、 IEEE 表現の操作によって実装されます( glibc、 musl)。
追加の std::nextafter オーバーロードは、 (A) とまったく同じように提供される必要はありません。これらは、最初の引数 num1 と2番目の引数 num2 に対して、次のことを保証するのに十分であればよいです。
|
(C++23まで) |
|
num1 と num2 が算術型の場合、 std::nextafter(num1, num2) は std::nextafter(static_cast</*共通浮動小数点型*/>(num1), そのような最高のランクとサブランクセを持つ浮動小数点型が存在しない場合、オーバーロード解決は提供されたオーバーロードから使用可能な候補を導出しません。 |
(C++23から) |
追加の std::nexttoward オーバーロードは、 (B) とまったく同じように提供される必要はありません。これらは、整数型の引数 num に対して、 std::nexttoward(num) が std::nexttoward(static_cast<double>(num)) と同じ効果を持つことを保証するのに十分であればよいです。
[編集] Example
#include <cfenv> #include <cfloat> #include <cmath> #include <concepts> #include <iomanip> #include <iostream> int main() { float from1 = 0, to1 = std::nextafter(from1, 1.f); std::cout << "The next representable float after " << std::setprecision(20) << from1 << " is " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "The next representable float after " << from2 << " is " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "The number 0.1 lies between two valid doubles:\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\nand " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nDifference between nextafter and nexttoward:\n"; long double dir = std::nextafter(from1, 1.0L); // first subnormal long double float x = std::nextafter(from1, dir); // first converts dir to float, giving 0 std::cout << "With nextafter, next float after " << from1 << " is " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "With nexttoward, next float after " << from1 << " is " << x << '\n'; std::cout << "\nSpecial values:\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "The next representable double after " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " is " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " raised FE_OVERFLOW\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " raised FE_INEXACT\n"; } // end FENV_ACCESS block float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) gives " << std::fixed << to5 << '\n'; auto precision_loss_demo = []<std::floating_point Fp>(const auto rem, const Fp start) { std::cout << rem; for (Fp from = start, to, Δ; (Δ = (to = std::nextafter(from, +INFINITY)) - from) < Fp(10.0); from *= Fp(10.0)) std::cout << "nextafter(" << std::scientific << std::setprecision(0) << from << ", INF) gives " << std::fixed << std::setprecision(6) << to << "; Δ = " << Δ << '\n'; }; precision_loss_demo("\nPrecision loss demo for float:\n", 10.0f); precision_loss_demo("\nPrecision loss demo for double:\n", 10.0e9); precision_loss_demo("\nPrecision loss demo for long double:\n", 10.0e17L); }
出力
The next representable float after 0 is 1.4012984643248170709e-45 (0x1p-149)
The next representable float after 1 is 1.0000001192092895508 (0x1.000002p+0)
The number 0.1 lies between two valid doubles:
0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
and 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
Difference between nextafter and nexttoward:
With nextafter, next float after 0 is 0
With nexttoward, next float after 0 is 1.4012984643248170709e-45
Special values:
The next representable double after 1.79769e+308 (0x1.fffffffffffffp+1023) is inf (inf)
raised FE_OVERFLOW
raised FE_INEXACT
std::nextafter(+0.0, -0.0) gives -0.000000
Precision loss demo for float:
nextafter(1e+01, INF) gives 10.000001; Δ = 0.000001
nextafter(1e+02, INF) gives 100.000008; Δ = 0.000008
nextafter(1e+03, INF) gives 1000.000061; Δ = 0.000061
nextafter(1e+04, INF) gives 10000.000977; Δ = 0.000977
nextafter(1e+05, INF) gives 100000.007812; Δ = 0.007812
nextafter(1e+06, INF) gives 1000000.062500; Δ = 0.062500
nextafter(1e+07, INF) gives 10000001.000000; Δ = 1.000000
nextafter(1e+08, INF) gives 100000008.000000; Δ = 8.000000
Precision loss demo for double:
nextafter(1e+10, INF) gives 10000000000.000002; Δ = 0.000002
nextafter(1e+11, INF) gives 100000000000.000015; Δ = 0.000015
nextafter(1e+12, INF) gives 1000000000000.000122; Δ = 0.000122
nextafter(1e+13, INF) gives 10000000000000.001953; Δ = 0.001953
nextafter(1e+14, INF) gives 100000000000000.015625; Δ = 0.015625
nextafter(1e+15, INF) gives 1000000000000000.125000; Δ = 0.125000
nextafter(1e+16, INF) gives 10000000000000002.000000; Δ = 2.000000
Precision loss demo for long double:
nextafter(1e+18, INF) gives 1000000000000000000.062500; Δ = 0.062500
nextafter(1e+19, INF) gives 10000000000000000001.000000; Δ = 1.000000
nextafter(1e+20, INF) gives 100000000000000000008.000000; Δ = 8.000000[編集] See also
| C ドキュメント ( nextafter について)
|