|
Message-ID: <31679941-f6c2-64fa-7a8d-6b6f7112c31@esi.com.au> Date: Mon, 17 Jun 2024 11:48:38 +1000 (AEST) From: Damian McGuckin <damianm@....com.au> To: MUSL <musl@...ts.openwall.com> Subject: roundf() (and round(), and ...) Before I submit any suggestion for a change to roundf/round/.., could I get a critique of the style to make sure I compy with the style guide. Also, I have not used anything except for the now default FLT_EVAL_METHOD so I need guidance as to where to use 'float_t'. However, the only place where such arithmetic (here) might be affected is the expression 'a + a' which is exact anyway so I think it is irrelevant. Thanks - Damian Code follows: float roundf(float x) { static const int b = 0x7f; const float a = fabsf(x); union { float f; uint32_t _f; } r = { a }, _x = { x }; if (((int) (r._f >> 23)) < b + 23) /* i.e. effectively |x| < 2^(p-1) */ { /* * capture the sign of the argument */ const uint32_t s = _x._f - r._f; /* * this should achieve rounding to nearest with any * ties (half-way cases) being rounded away-from-zero. * (is it wise to use uint32_t instead of int32_t here?) */ const uint32_t rf = ((uint32_t) (a + a)) - (uint32_t) a; x = (r.f = (float) rf, r._f |= s, r.f); } return x; } Note that as per the latest IEEE-754 standard, the above does not raise an exception in the event of the rounding being inexact. This is not backwards compatible with the existing MUSL equivalents. While it is another issue altogether, this latest standard also drops the nearbyint() in favour of routines called (as per the C standard) 'roundevenf()/roundeven()/...'.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.