Click or drag to resize

MoreMathSin Method

Computes the sine of the given value to full significance over the full range of arguments.

Namespace:  Meta.Numerics
Assembly:  Meta.Numerics (in Meta.Numerics.dll) Version: 4.1.4
public static double Sin(
	double x


Type: SystemDouble
The argument.

Return Value

Type: Double
The value of sin(x).

This method addresses several subtle shortcomings of the Sin(Double) method. One shortcoming, quite striking but rarely encountered, is that Sin(Double) returns entirely wrong results very large arguments -- for x larger than about 1020, it simply returns the argument as the function value! (I have no idea why the base class library designers did not at least choose to return NaN, so as to signal to the caller that the result should not be trusted. No floating point standard specifies this crazy behavior.) Another shortcoming, more commonly encountered but often unnoticed, is that for large but not necessarily very large arguments, function values loose precision, particularly near zeros of the function.

One way to view these shortcomings is that they are justified by the uncertainty inherent in floating point representations. In this view, any Double should be seen as an uncertain value with a relative error of ~10-16. If the argument is large enough, then the absolute size of this error can be as large or larger than 2π; in this circumstance we should not expect to be able to say anything about the value (except, of course, that it is between -1 and +1, which is violated by the designers' crazy choice to return the argument as the value). Even if the absolute error is just a non-negligible faction of 2π, there is a non-negligible fraction of the values between -1 and +1 in the corresponding range of function values; any of these values is as possible as any other as a value for the sine of our uncertain argument, so we should be satisfied with any returned value in this non-negligible range.

A different view is that it is better to regard every representable floating point value as some exact rational number, and when computing functions of floating point numbers, we should strive to return the representable floating point value nearest to the actual function value for that exact rational. Callers are unlikely to complain if we are careful in this regard, and this behavior is particularly useful when the argument is an intermediate result that the programmer may not even realize has become large. Thus is the view that we adopt, and therefore we provide this improved trigonometric function.

For typical arguments, say between -104 and 104, the extra cost of calling this function instead of Sin(Double) is just a couple of comparisons and a single floating point operation; less than 0.1% of arguments in this range are then routed to our much slower, high-accuracy algorithm. We therefore suggest that, for general use, you prefer this method over Sin(Double); only in very unusual situations where (i) you are guaranteed never to encounter very large arguments, (ii) full precision values are not required, and (iii) the run-time of your application is critical and dominated by trigonometric calculations, should you prefer the base class library method.

See Also