TheDeveloperBlog.com

C# Math.Cos, Sin and Tan: Inverse and Hyperbolic

Cos, sin, tan. Trigonometric functions are available in the .NET Framework. We test them for correctness. They are found in the Math type in the System namespace. We examine the Acos, Cos, Cosh, Asin, Sin, Sinh, Atan, Tan and Tanh methods.

Example. To begin, we present a program that simply calls Acos, Cos, Cosh, Asin, Sin, Sinh, Atan, Tan and Tanh. All of these methods receive arguments in units of radians represented by the double type.

Double

Next: In this program, the C# compiler implicitly converts the integer arguments into double arguments.

C# program that uses trigonometric methods

using System;

class Program
{
static void Main()
{
Console.WriteLine(Math.Acos(0)); // Inverse cosine
Console.WriteLine(Math.Cos(2)); // Cosine
Console.WriteLine(Math.Cosh(5)); // Hyperbolic cosine

Console.WriteLine(Math.Asin(0.2)); // Inverse sine
Console.WriteLine(Math.Sin(2)); // Sine
Console.WriteLine(Math.Sinh(-5)); // Hyperbolic sine

Console.WriteLine(Math.Atan(-5)); // Inverse tangent
Console.WriteLine(Math.Tan(1)); // Tangent
Console.WriteLine(Math.Tanh(0.1)); // Hyperbolic tangent
}
}

Result

1.5707963267949
-0.416146836547142
74.2099485247878
0.201357920790331
0.909297426825682
-74.2032105777888
-1.37340076694502
1.5574077246549
0.0996679946249558  More comments. If you want to compare the results of these methods with other languages, you can use a JavaScript scientific calculator available on the Internet. The calculator does not provide the hyperbolic methods.

Note: The Acos, Cos, Asin, Sin, Atan, and Tan methods returned the same results but to a different decimal place in both languages.

Scientific Calculator

More on these functions. One of the more interesting things to do with these methods in a demonstration program is to graph their results. If you look at the MathWorks site, you can check the graphs.

Also: The MathWorks site provides more information about their mathematical meanings.

Trigonometry: MathWorks

Optimization. I am curious. I recently had a chance to use Math.Sin in a program. In this program only the first several integers were used as arguments to Sin. I decided to benchmark Math.Sin to see if it was worth optimization.

I found that Math.Sin, even on small ints, takes a fair amount of processing time. I then built a code generation program. It prints out part of a switch statement. We use it to generate an optimized Math.Sin method.

SwitchCase
C# program that generates Math.Sin switch

using System;

class Program
{
static void Main()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("case {0}:", i);
Console.WriteLine("    return {0};", Math.Sin(i));
}
}
} Next, I developed a method called SinFast. It replaces Math.Sin calls on small ints with a switch-statement. This next program shows that method and benchmarks it. The results are afterwards described.

C# program that benchmarks Math.Sin

using System;
using System.Diagnostics;

class Program
{
/// <summary>
/// Optimized version of Sin.
/// </summary>
static double SinFast(int value)
{
switch (value)
{
case 0:
return 0;
case 1:
return 0.841470984807897;
case 2:
return 0.909297426825682;
case 3:
return 0.141120008059867;
case 4:
return -0.756802495307928;
case 5:
return -0.958924274663138;
case 6:
return -0.279415498198926;
case 7:
return 0.656986598718789;
case 8:
return 0.989358246623382;
case 9:
return 0.412118485241757;
default:
return Math.Sin(value);
}
}

const int _max = 1000000;
static void Main()
{
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
for (int a = 0; a < 10; a++)
{
double v = Math.Sin(a);
if (v == -1)
{
throw new Exception();
}
}
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
for (int a = 0; a < 10; a++)
{
double v = Program.SinFast(a);
if (v == -1)
{
throw new Exception();
}
}
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
}
}

Output

301.76 ns
35.82 ns The optimized method, on the expected inputs, performs almost ten times faster. If you have a call to Math.Sin with a limited or expected range of input, generating a lookup table (with switch) may be helpful.

Benchmark

Summary. The .NET Framework and C# language provides the standard trigonometric methods, including Acos, Cos, Cosh, Asin, Sin, Sinh, Atan, Tan, and Tanh. These implement trigonometric identities and include inverse and hyperbolic functions.