5 ms·
Of possible interest, I researched a related issue once and here's what I found: The particular approximation used by the FPU instructions fsin and fcos is val
by CurtHagenlocher 12y ago
Of possible interest, I researched a related issue once and here's what I found:
The particular approximation used by the FPU instructions fsin and fcos is valid in the domain [-π /4, π /4]. Inputs outside this domain are reduced by taking the remainder when dividing by π /4 and then using trigonometric identities to fix up values in the other three quadrants (ie sin(x) = sin(π /2 – x) for x in [π /4, π /2].
The Intel FPU is “off” because it uses an approximation for π /4 when performing the reduction. In the mid 90s, some engineers at AMD figured out how to do a more precise reduction and implemented this reduction in the K5 FPU. AMD went back to being bit-for-bit compatible with the x87 behavior in the very next generation of their CPUs, presumably because it either broke or appeared to break too many applications.
- CurtHagenlocher 12y agoI just noticed that Bruce has moved from Valve to Google... . Interesting!
- sillysaurus3 12y agoIt's not possible to implement a more precise fsin() without breaking apps? One scenario I can imagine an app breaking is if someone executed fsin(x), pasted the result into their code, and then tested some other float against it using the == operator. I suppose a more common breakage scenario would be if someone did something like floor(x + fsin(x)), since that'd very slightly change where the floor "triggers" with respect to the input. But how could that cause an app to break? Every scenario I can think of comes back to someone using == to test floats, which everyone knows is a no-no for dynamic results, such as the output of a function like fsin(). I guess a programmer wouldn't really expect the result of "x + fsin(x)" to ever change for a certain value of x, so maybe they executed it with that certain value, stored the result, and did an equality comparison later, which would always work unless the implementation of fsin() changed, and the thought process went something like, "This should be reliable because realistically the implementation of fsin() won't change." Can anyone think of some obvious way that making fsin() more accurate could cause serious breakage in an app that isn't testing floats with the equality operator?
- Guvante 12y ago> One scenario I can imagine an app breaking is if someone executed fsin(x), pasted the result into their code, and then tested some other float against it using the == operator. While this sounds grandious, thanks to aggressive inlining this could be the case even if you wrote in your logic: sin(x) == sin(constant) Or even the following depending on your choice of delta. abs(sin(x) - sin(constant) < delta
- sillysaurus3 12y agoIs it even valid for a compiler to transform sin(constant) into a hardcoded constant embedded into the executable? I guess since sin(x) is computed by an FPU in hardware, then it's inherently "dynamically linked." But in that case, why is it valid for a compiler to transform sin(constant) into a hardcoded result? Is there some standard somewhere which says that the implementation of sin/cos/etc can't ever change, and therefore it's valid for the compiler to do that? Or do compilers just make an assumption that the implementation of sin(x) won't ever change?
- darkmighty 12y agoIt breaks binary compatibility. The compiler substitutes some value (e.g. the broken value), so if the sin(x) evaluation changes (to the correct one), then binary execution will fail.
- DannyBee 12y agoWhy would the compiler substitute the broken value unless the compiler was broken? Compilers generally don't use specialized local architecture instructions to compute their results, because they can't (It would break cross-compiling or targeting different platforms in a lot of cases) In fact, it's more likely the other way around: Compiler substitutes proper value. actual calls on sin(x) on the local platform give wrong answer.
- DannyBee 12y ago"but if it's dynamic, is it even valid for a compiler to transform sin(constant) into a hardcoded constant embedded into the executable?" Yes. I honestly don't remember all the rules here, but it does in fact do so, legally.