# How to design a sin and an arcsin function such that arcsin(sin(x))=x, where x is a finite precision floating point number

As commonly known for programming on computer, if x is a finite precision floating-point number such as double/float in C language, arcsin(sin(x)) is usually not equal to x due to the numerical issue. I'm wondering whether there is a way to design a sin function and an arcsin function such that arcsin(sin(x))=x where x is an fixed-size multi-precision floating-point number. Ideally, both sin and arcsin function would have error guarantee.

On solution would be to approximate the sin using linear piecewise function. However, it would take a lot of memory to store all functions if we want to achieve a very accurate approximation.

• I suppose you are restricting yourself to a specific domain such as $[-\pi/2,\pi/2]$, because otherwise you'd have to deal with the fact that the sine is not injective. It isn't impossible, but it would surely return a wildly discontinuous arcsin() function, since values close to 0 have to be mapped back to 0, $\pi$, $2\pi$, ... Mar 21 at 13:41
• Yes, x is only in $[-\pi/2, \pi/2]$ Mar 21 at 13:45

That seems impossible to do with a small numerical error, because of cardinality reasons. Consider for instance the much simpler case of the function $$f(x) = x^2$$ over $$[0,1]$$. This function maps $$[0,1/2]$$ into $$[0,1/4]$$. But the floating-point numbers in $$[0,1/4]$$ are much fewer than the numbers in $$[0,1/2]$$, and hence this is impossible to do.
To turn this into a mathematical argument: assume that your number system contains $$N$$ numbers in $$[0,1/2)$$, the number $$1/2$$ (which we assume to be an exact floating-point number, for simplicity) and $$M$$ numbers in $$(1/2,1]$$. Consider your implementation $$g(x)$$ which is supposed to approximate the map $$f(x) = x^2$$. Since you want it to be injective, the $$N+1$$ numbers in $$[0,1/2]$$ must be mapped to $$N+1$$ different floating point numbers. In particular, at least one of them must be in $$[1/2,1]$$, since there are only $$N$$ floating-point numbers inside $$[0,1/2)$$. So there must be a number $$a\in [0,1/2]$$ for which $$g(a) \geq 1/2$$, which is a very large error to have since $$f(a) \leq 1/4$$.
• Yes, you can construct such maps. I have a construction in mind but it's not particularly pretty as it is based on set-theoretic ideas. The idea is that you can partition the domain X = [-pi/2, pi/2] into intervals $I_1, I_2, \dots, I_n$ of width $\varepsilon$, and map in any way the rationals in the interval $I_k$ into those in the interval $f(I_k)$ bijectively. This should give you a map that is close to the sine in the L_inf distance and is a bijection on the rationals. Mar 21 at 18:32
• @user3677630 The pigeon hole principle this answer is based on points out the problem when the inner function is contracting while the outer function is expanding. However, it can work fine the other way around: For example, in the absence of overflow/underflow, IEEE-754 arithmetic guarantees that $\sqrt{x^2}=x$ while this cannot be guaranteed for $(\sqrt{x})^2$. For your use case, could you reverse the order of operations, that is, use $\sin^{-1} x$ as the inner function? Mar 22 at 6:49
• @user3677630 For some $f$. Where "some" is likely "few". I would not know how to prove that it works in a particular case, but some people do: "We have proved that, using radix $2$ and a precision greater than $1$, the rounded computation of $\sqrt{a^2}$ is indeed $|a|$." You might want to try something like $\ln(\exp(x))$ first as an easier case and see what you can prove about it. Note that correctly-rounded transcendental functions fall only under the optional provisions of IEEE-754 and there are few libraries providing them (see crlibm). Mar 24 at 5:18