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 /* 浮點型別 */ 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 /* 浮點型別 */ 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
的過載作為引數 from 和 to 的型別。(C++23 起)
庫為所有 cv 非限定浮點型別提供了 |
(C++23 起) |
std::nextafter
過載。std::nexttoward
過載,這些型別被視為 double。目錄 |
[編輯] 引數
from, to | - | 浮點數或整數值 |
[編輯] 返回值
如果未發生錯誤,則返回從 from 到 to 方向的下一個可表示值。如果 from 等於 to,則返回 to。
如果由於溢位導致範圍錯誤,則返回 ±HUGE_VAL、±HUGE_VALF
或 ±HUGE_VALL
(與 from 具有相同的符號)。
如果由於下溢導致範圍錯誤,則返回正確結果。
[編輯] 錯誤處理
錯誤按 math_errhandling 指定的方式報告。
如果實現支援 IEEE 浮點運算 (IEC 60559),
- 如果 from 是有限的,但預期結果是無窮大,則引發 FE_INEXACT 和 FE_OVERFLOW。
- 如果 from 不等於 to 且結果是次正規數或零,則引發 FE_INEXACT 和 FE_UNDERFLOW。
- 在任何情況下,返回值都與當前舍入模式無關。
- 如果 from 或 to 是 NaN,則返回 NaN。
[編輯] 注意
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)。
不要求額外提供與 (A) 完全相同的 std::nextafter
過載。它們只需足以確保對於它們的第一個引數 num1 和第二個引數 num2:
|
(直至 C++23) |
如果 num1 和 num2 具有算術型別,則 std::nextafter(num1, num2) 的效果與 std::nextafter(static_cast</*common-floating-point-type*/>(num1), 如果不存在具有最高等級和次等級的浮點型別,則過載決議不會從提供的過載中產生可用的候選函式。 |
(C++23 起) |
不要求額外提供與 (B) 完全相同的 std::nexttoward
過載。它們只需足以確保對於其整數型別的引數 num,std::nexttoward(num) 的效果與 std::nexttoward(static_cast<double>(num)) 相同。
[編輯] 示例
#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
[編輯] 參閱
C 文件 關於 nextafter
|