* Returns true if the floating-pointing rounding mode is to 'nearest'. * It is the default on most system. This function is meant to be inexpensive. * Credit : @mwalcott3 */
| 4560 | * Credit : @mwalcott3 |
| 4561 | */ |
| 4562 | fastfloat_really_inline bool rounds_to_nearest() noexcept { |
| 4563 | // https://lemire.me/blog/2020/06/26/gcc-not-nearest/ |
| 4564 | #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) |
| 4565 | return false; |
| 4566 | #endif |
| 4567 | // See |
| 4568 | // A fast function to check your floating-point rounding mode |
| 4569 | // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/ |
| 4570 | // |
| 4571 | // This function is meant to be equivalent to : |
| 4572 | // prior: #include <cfenv> |
| 4573 | // return fegetround() == FE_TONEAREST; |
| 4574 | // However, it is expected to be much faster than the fegetround() |
| 4575 | // function call. |
| 4576 | // |
| 4577 | // The volatile keyword prevents the compiler from computing the function |
| 4578 | // at compile-time. |
| 4579 | // There might be other ways to prevent compile-time optimizations (e.g., |
| 4580 | // asm). The value does not need to be std::numeric_limits<float>::min(), any |
| 4581 | // small value so that 1 + x should round to 1 would do (after accounting for |
| 4582 | // excess precision, as in 387 instructions). |
| 4583 | static float volatile fmin = std::numeric_limits<float>::min(); |
| 4584 | float fmini = fmin; // we copy it so that it gets loaded at most once. |
| 4585 | // |
| 4586 | // Explanation: |
| 4587 | // Only when fegetround() == FE_TONEAREST do we have that |
| 4588 | // fmin + 1.0f == 1.0f - fmin. |
| 4589 | // |
| 4590 | // FE_UPWARD: |
| 4591 | // fmin + 1.0f > 1 |
| 4592 | // 1.0f - fmin == 1 |
| 4593 | // |
| 4594 | // FE_DOWNWARD or FE_TOWARDZERO: |
| 4595 | // fmin + 1.0f == 1 |
| 4596 | // 1.0f - fmin < 1 |
| 4597 | // |
| 4598 | // Note: This may fail to be accurate if fast-math has been |
| 4599 | // enabled, as rounding conventions may not apply. |
| 4600 | #ifdef FASTFLOAT_VISUAL_STUDIO |
| 4601 | #pragma warning(push) |
| 4602 | // todo: is there a VS warning? |
| 4603 | // see |
| 4604 | // https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013 |
| 4605 | #elif defined(__clang__) |
| 4606 | #pragma clang diagnostic push |
| 4607 | #pragma clang diagnostic ignored "-Wfloat-equal" |
| 4608 | #elif defined(__GNUC__) |
| 4609 | #pragma GCC diagnostic push |
| 4610 | #pragma GCC diagnostic ignored "-Wfloat-equal" |
| 4611 | #endif |
| 4612 | return (fmini + 1.0f == 1.0f - fmini); |
| 4613 | #ifdef FASTFLOAT_VISUAL_STUDIO |
| 4614 | #pragma warning(pop) |
| 4615 | #elif defined(__clang__) |
| 4616 | #pragma clang diagnostic pop |
| 4617 | #elif defined(__GNUC__) |
| 4618 | #pragma GCC diagnostic pop |
| 4619 | #endif |
no outgoing calls
no test coverage detected