* 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 */
| 3177 | * Credit : @mwalcott3 |
| 3178 | */ |
| 3179 | fastfloat_really_inline bool rounds_to_nearest() noexcept { |
| 3180 | // https://lemire.me/blog/2020/06/26/gcc-not-nearest/ |
| 3181 | #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) |
| 3182 | return false; |
| 3183 | #endif |
| 3184 | // See |
| 3185 | // A fast function to check your floating-point rounding mode |
| 3186 | // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/ |
| 3187 | // |
| 3188 | // This function is meant to be equivalent to : |
| 3189 | // prior: #include <cfenv> |
| 3190 | // return fegetround() == FE_TONEAREST; |
| 3191 | // However, it is expected to be much faster than the fegetround() |
| 3192 | // function call. |
| 3193 | // |
| 3194 | // The volatile keywoard prevents the compiler from computing the function |
| 3195 | // at compile-time. |
| 3196 | // There might be other ways to prevent compile-time optimizations (e.g., asm). |
| 3197 | // The value does not need to be std::numeric_limits<float>::min(), any small |
| 3198 | // value so that 1 + x should round to 1 would do (after accounting for excess |
| 3199 | // precision, as in 387 instructions). |
| 3200 | static volatile float fmin = std::numeric_limits<float>::min(); |
| 3201 | float fmini = fmin; // we copy it so that it gets loaded at most once. |
| 3202 | // |
| 3203 | // Explanation: |
| 3204 | // Only when fegetround() == FE_TONEAREST do we have that |
| 3205 | // fmin + 1.0f == 1.0f - fmin. |
| 3206 | // |
| 3207 | // FE_UPWARD: |
| 3208 | // fmin + 1.0f > 1 |
| 3209 | // 1.0f - fmin == 1 |
| 3210 | // |
| 3211 | // FE_DOWNWARD or FE_TOWARDZERO: |
| 3212 | // fmin + 1.0f == 1 |
| 3213 | // 1.0f - fmin < 1 |
| 3214 | // |
| 3215 | // Note: This may fail to be accurate if fast-math has been |
| 3216 | // enabled, as rounding conventions may not apply. |
| 3217 | #if FASTFLOAT_VISUAL_STUDIO |
| 3218 | # pragma warning(push) |
| 3219 | // todo: is there a VS warning? |
| 3220 | // see https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013 |
| 3221 | #elif defined(__clang__) |
| 3222 | # pragma clang diagnostic push |
| 3223 | # pragma clang diagnostic ignored "-Wfloat-equal" |
| 3224 | #elif defined(__GNUC__) |
| 3225 | # pragma GCC diagnostic push |
| 3226 | # pragma GCC diagnostic ignored "-Wfloat-equal" |
| 3227 | #endif |
| 3228 | return (fmini + 1.0f == 1.0f - fmini); |
| 3229 | #if FASTFLOAT_VISUAL_STUDIO |
| 3230 | # pragma warning(pop) |
| 3231 | #elif defined(__clang__) |
| 3232 | # pragma clang diagnostic pop |
| 3233 | #elif defined(__GNUC__) |
| 3234 | # pragma GCC diagnostic pop |
| 3235 | #endif |
| 3236 | } |
no outgoing calls
no test coverage detected