I just read this topic (especially the last comments).
Then I was wondering, why we actually need this was of giving the remainder. But it seems, that not many people "on google" were interested in that before...
I just read this topic (especially the last comments).
Then I was wondering, why we actually need this was of giving the remainder. But it seems, that not many people "on google" were interested in that before...
If you're looking for reasons why you would want it, one is for what is known as "range reduction"
Let's say you want sind
function for computing the sine of an argument in degrees. A naive way to do this would be
sind(x) = sin(x*pi/180)
However pi
here is not the true irrational number pi
, but instead the floating point number closest to pi
. This leads to things like sind(180) == 1.2246467991473532e-16
, and SO questions like this and this (and many, many more).
But sine is a periodic function, so if we compute
remainder(x,90.0)
we get a value on the interval [-45,45]. Note that 0, 90, 180, 270, etc. become exactly 0, and multiplying by pi/180
is still 0. Therefore taking the appropriately signed sin
or cos
, we can get the exact result at these values (and if you do some basic error analysis, you can demonstrate that it also reduces the error at other values).
Two follow up points:
sin
or cos
to use? Well, that's what remquo
is for.sind(30.0) == 0.5
exactly, due to the vagaries of intermediate rounding. There are ways to fix this, e.g. see what the Julia library does.Can be used to get the nearest multiple:
double NearestMultiple(int numerator, int denominator)
{
return numerator - double.Ieee754Remainder(numerator, denominator);
}
> NearestMultiple(11, 3)
12
> NearestMultiple(10, 3)
9
© 2022 - 2024 — McMap. All rights reserved.