Using my range analysis program:
Given: sqrt(1-sqr(x))
where sqr(x) is x^2, we conclude that the result is in the range [0,1], and x must be in the range [-1,1].
Given: sqrt(1-x*x)
we conclude that the result is in the range [0,inf), and x must be in the range (minf,inf).
[Note that x*x is not the same as x^2, because x*x is a binary operation on two arguments that
happen to be the same ranges, while x^2 is a unary operation on a single range.]
Given: (if x>0 then sqrt(1-x*x) else sqrt(1-x*x))
we conclude that the result is in the range [0,1], and x must be in the range (minf,inf).
Using if-then-else to force a "case analysis" helps, but this is still not as good as
using the sqr() function, which knows how to compute its inverse.
We can do a syntactic hack which recognizes "<var>*<var>", where we have the _same_ variable;
this is equivalent to a "macro" expanding to "sqr(<var>)".
Given: sqrt(1-exp(2*log(abs(x))))
we conclude that the result is in the range [0,1), and x must be in the range [-1,0) union (0,1];
i.e., we get a sharper range for x, but range analysis also correctly concludes that this
expression will fail for x=0.
Given: (if x=0 then 1 else sqrt(1-exp(2*log(abs(x))))
we conclude that the result is in the range [0,1], and x must be in the range [-1,1]; i.e.,
we have plugged the hole at x=0.
Given: (exp(x)+exp(-x))/2
we conclude that the result is in the range (0,inf), and x is any real number. Note that
we can't conclude that the result >=1, because the range analysis doesn't know that
exp(x) and exp(-x) are correlated.
Given: (exp(x)+exp(-x))/2 = 3
we conclude that x is in the range (-30/17, 30/17), which is pretty good, considering
we don't know about acosh() !
Given: (exp(x)-exp(-x))/2
we conclude that the result is in the range (minf,inf), and x is any real number.
Given: (exp(x)-exp(-x))/2 = 3
we conclude that x is in the range (1309/720, 11/6), which is astoundingly good, considering
we don't know anything about asinh() !
Given: (exp(x)-exp(-x))/2 = 1/2
we conclude that x is in the range (39/83, 23/45), which is astoundingly good.
BTW, I think that all languages should implement "sqr(x)" as a separate routine from "x*x",
because one can then rely on all kinds of optimizations for squaring which aren't available
for general multiplications.