[Mesa-dev] [PATCH 1/3] mesa: Replace _mesa_round_to_even() with _mesa_roundeven().

Matt Turner mattst88 at gmail.com
Thu Mar 12 15:26:34 PDT 2015


On Thu, Mar 12, 2015 at 2:59 PM, Carl Worth <cworth at cworth.org> wrote:
> On Thu, Mar 12 2015, Matt Turner wrote:
>> +/* The C standard library has functions round()/rint()/nearbyint() that round
>> + * their arguments according to the rounding mode set in the floating-point
>> + * control register. While there are trunc()/ceil()/floor() functions that do
>> + * a specific operation without modifying the rounding mode, there is no
>> + * roundeven() in any version of C.
>> + *
>> + * Technical Specification 18661 (ISO/IEC TS 18661-1:2014) adds roundeven(),
>> + * but it's unfortunately not implemented by glibc.
>> + *
>> + * This implementation differs in that it does not raise the inexact exception.
>> + */
>
> This documentation needs the actual description of the behavior of the
> function. Most of the above comment is commentary on the implementation
> itself.
>
> Perhaps something like the following?
>
>         Round \x to the nearest even integer (returned in floating-point
>         format).
>
>         Note: This function is similar to roundeven() as specified by
>         Technical Specification 18661 (ISO/IEC TS 18661-1:2014),
>         differing only in that _mesa_roundeven() won't necessarily raise
>         the inexact exception as roundeven() would.

Sounds good.

> Then, (within the function body itself?), it makes sense to have a
> comment on the implementation:
>
>         When glibc eventually implements the standardized roundeven() we
>         could use it directly. Until then, the available C standard
>         library functions have the following limitations:
>
>                 round()/rint()/nearbyint(): Behavior varies depending on
>                 the rounding mode set in the floating-point control
>                 register.
>
>                 trunc()/ceil()/floor(): These specify rounding without
>                 relying on the rounding mode, but none give the rounding
>                 behavior desired for _mesa_roundeven().

I don't know why we would want to document that these functions don't
implement the behavior we want. That seems obvious enough...

>         <But since none of those work??? See my questions below...>

I'm not sure what you mean. My intention in noting the existence of
trunc/ceil/floor is to note that there isn't an analogous function
with round-to-even behavior -- we have to use rint() with a particular
rounding mode.

>> +static inline float
>> +_mesa_roundevenf(float x)
>> +{
>> +   float ret;
>> +   /* Assume that the floating-point rounding mode has not been changed from
>> +    * the default (Round to nearest).
>> +    */
>> +   ret = rintf(x);
>> +   return ret;
>> +}
>
> But after all that commentary about how rint() doesn't provide what's
> needed, here the implementation is just using it anyway?

I think you misread. rint() *does* provide the behavior we want
(round-to-nearest, half to even) when the rounding mode is the default
round-to-nearest.

As Eric noted in his original patch, the man pages for
rint(3)/nearbyint(3) don't describe the half-to-even behavior but
round(3) does:

> These  functions  round  x  to  the  nearest  integer, but round halfway cases away from zero (regardless of the current rounding direction, see fenv(3)), instead of to the nearest even integer like rint(3).

Maybe I should send a patch to the Linux man-pages project too.

> The comment here, (and even any history of "other parts of mesa make the
> same assumption"), doesn't give the code adequate robustness. So at
> least an assert is needed here. Is this correct: ?
>
>         assert (fegetround() == FE_TONEAREST);

I don't really want to do this. We rely on the default rounding mode
everywhere. I don't think asserting here is useful. Also it requires
adding code for MSVC since it doesn't have fegetround().

> But beyond that, I'm actually confused---how can the default rounding
> mode (rounding toward nearest number, right?) give us an adequate
> implementation for roundeven()?

Answered above.


More information about the mesa-dev mailing list