3 The .NET Framework Math Class - Methods
Tải bản đầy đủ - 0trang
The .NET Framework Math Class Library
75
The Power method, Math.Pow(b,x), is used to calculate bx where b and x are both
real numbers. Both of these input variables along with the resulting output are of
type double. This method is declared internally as:
public static double Pow(double b, double x);
√
In particular, when the exponent x = 1/2 = 0.5 then bx = b1/2 = b. This special
case of the Power method occurs often enough in applications that the .NET Framework Math Class Library provides its own internal method, Math.Sqrt(x), for taking
the square root of a real number specified by the input parameter x. This method is
declared internally as:
public static double Sqrt(double x);
Both the input parameter, x, and the value returned by this method are of type double.
If x ≥ 0, this method returns the positive square root of x. If x < 0, then this method
returns NaN without throwing an exception. If x = NaN or if x = PositiveInfinity
then that value is returned instead.
When the base of interest, b, is the natural base e, then the expression ex is called
the exponential function. The method, Math.Exp(x), is used to raise e to a specific
power given by the input parameter x. This method is declared internally as:
public static double Exp(double x);
Note that both the input parameter x and the resulting output given by Math.Exp(x)
are of type double. If the input parameter x equals NaN or PositiveInfinity then
that value is returned instead without throwing an exception. However, if x equals
NegativeInfinity then 0.0 is returned as expected.
The inverse of the exponential function ex is the natural logarithm, or logarithm
to base e and is commonly written as ln(x) or log(x). The method Math.Log(x), is
used for calculating the natural base e logarithm of a number specified by the input
parameter x and is declared internally as:
public static double Log(double x);
If x > 0, then Math.Log(x) returns the natural logarithm of x. That is, ln(x) or
loge (x). If x = 0 then Math.Log(x) returns NegativeInfinity. If x < 0 then Math.
Log(x) returns NaN.
The method Math.Log(x) can also be overloaded to return the logarithm of a number in another base as specified by the input parameters x and newBase, respectively.
In this case, the method is declared internally as:
public static double Log(double x, double newBase);
If x > 0, and newBase ≥ 0 then Log(x, newBase) returns the logarithm of x in the
base newBase. That is, lognewBase x. If newBase < 0 then Log(x, newBase) returns
NaN. If x = 0 then Math.Log(x, newBase) returns NegativeInfinity. If x < 0 then
Math.Log(x, newBase) returns NaN.
Base 10 logarithmic calculations occurs frequently enough in applications that the
.NET Framework Math Class Library provides its own internal method for taking
the base 10 logarithm of a real number. The method Math.Log10(x), is used for
© 2010 by Taylor and Francis Group, LLC
76
Numerical Methods, Algorithms and Tools in C#
calculating the base 10 logarithm of a number as specified by the input parameter x.
This method is declared internally as:
public static double Log10(double x);
If x > 0, then Math.Log10(x) returns the base 10 logarithm of x. That is, log10 (x).
If x = 0 then Math.Log10(x) returns NegativeInfinity. If x < 0 then the method
Math.Log10(x) returns NaN.
The following code snippet illustrates the use of the power, exponential and logarithmic methods that were just discussed.
public static void PowerExpLog_Example()
{
double b = 2.75, x = 3.25, newBase = 8.0;
Console.WriteLine("Exp({0}) = {1}",x,Math.Exp(x));
Console.WriteLine("Log({0}) = {1}\n",Math.Exp(x),
Math.Log(Math.Exp(x)));
Console.WriteLine("Pow({0},{1}) = {2}",b,x,Math.Pow(b, x));
Console.WriteLine("Log10({0})/Log10({1}) = {2}\n",
Math.Pow(b,x),b,Math.Log10(Math.Pow(b,x))/Math.Log10(b));
Console.WriteLine("Log{0}({1}) = {2}",newBase,x,
Math.Log(x,newBase));
Console.WriteLine("Pow({0},{1}) = {2}",newBase,
Math.Log(x,newBase),Math.Pow(newBase,Math.Log(x,newBase)));
}
2.3.3 Special Multiplication, Division and Remainder Methods
Sometimes when two 32-bit integers are multiplied together the final product will be
larger than the maximum allowed value that the 32-bit integer data type can hold.
Although one could go back and switch the variable declarations to that of another
data type that would be capable of accepting larger numbers, there may be one or
more compelling reasons for the variables being multiplied to retain their original
integer data type. As a result, the .NET Framework Math Class Library provides a
special method called Math.BigMul(x,y) that can be used for calculating the product
of two 32-bit integers and producing an output that is then expressed as a 64-bit
integer. This method is declared internally as:
public static long BigMul(int x, int y);
Similarly, the .NET Framework Math Class Library provides a special method,
Math.DivRem, for calculating the quotient of two integers returning any remainder in
an output parameter. The DivRem method can be overloaded and used for both 32-bit
and 64-bit integers and is declared internally as:
public static int DivRem(int x,int y,out int remainder);
public static long DivRem(long x,long y,out long remainder);
© 2010 by Taylor and Francis Group, LLC
The .NET Framework Math Class Library
77
Finally, the method, Math.IEEERemainder(x,y), returns only the remainder obtained from the division of two specified numbers of type double. The return value
is also of type double. This method is declared internally as:
public static double IEEERemainder(double x,double y);
where the parameters x is the dividend and y is the divisor. This method actually
computes the expression x − yQ where Q = x/y is rounded to the nearest integer.
If Q falls halfway between two integers, then the even integer is returned. If the
expression x − yQ is zero, then the value +0 is returned if x > 0 otherwise the value
−0 is returned if x < 0. If y = 0, then NaN is returned.
The following example illustrates the use of BigMul, DivRem and IEERemainder
methods:
public static void MultDivRem_Example()
{
int int1 = Int32.MaxValue;
int int2 = Int32.MaxValue;
int intResult;
long longResult;
double divisor, doubleResult;
longResult=Math.BigMul(int1,int2);
Console.WriteLine("{0}*{1}={2}\n",int1,int2,longResult);
intResult=Math.DivRem(int1,2,out int2);
Console.WriteLine("{0}/{1}={2}, with a remainder of {3}.",int1,2,
intResult,int2);
String str="The IEEE remainder of {0:e}/{1:f} is {2:e}";
divisor=2.0;
doubleResult=Math.IEEERemainder(Double.MaxValue,divisor);
Console.WriteLine(str,Double.MaxValue,divisor,doubleResult);
divisor=3.0;
doubleResult=Math.IEEERemainder(Double.MaxValue,divisor);
Console.WriteLine(str,Double.MaxValue,divisor,doubleResult);
}
2.3.4 The Absolute Value Method
For any real number x the absolute value or modulus of x is denoted by |x| and is
defined as
x if x ≥ 0
|x| =
−x if x < 0
As can be seen from the above definition, the absolute value of x is always either positive or zero, but never negative. The .NET Framework Math Class Library provides
the method Math.Abs(x) that returns the absolute value of a number as specified by
the input parameter x. This method is declared internally as:
public static [type] Abs([type] x);
© 2010 by Taylor and Francis Group, LLC
78
Numerical Methods, Algorithms and Tools in C#
The input parameter, x, and the return value are of the same data type as given by the
unspecified label [type] which indicates that this method can be overloaded with the
following data types: decimal, double, int16, int32, int64, sbyte, single.
If the input parameter x is equal to NegativeInfinity or PositiveInfinity, the
return value is PositiveInfinity. If the input parameter x is equal to NaN, the
return value is NaN. The following code snippet illustrates the use of the method
Math.Abs(x).
double x = -2.0;
Console.WriteLine("Before:{0,-5} After:{1,-5}",x,Math.Abs(x));
which will display the following output on the monitor screen:
Before: -2.0
After: 2.0
2.3.5 The Sign Method
The sign function is a mathematical function that extracts the sign of a real number.
To avoid confusion with the trigonometric sine function, this function is often called
the signum function after the Latin form of the word “sign”. The signum function of
a real number x is defined as follows:
⎧
⎪
⎨−1 if x < 0
sng(x) =
0 if x = 0
⎪
⎩
+1 if x > 0
The method, Math.Sign(x), returns a value indicating the sign of a number specified
by the input parameter x. This method is declared internally as:
public static int Sign([type] x);
The input parameter, x, is of a data type given by the label [type] which indicates
that this method can be overloaded with the following data types: int16, int32,
int64, sbyte, single, decimal, double. The following code snippet illustrates
the use of the Math.Sign(x) method:
string str = "The sign of {0} is {1}";
double x = 5.0, y = 0.0, z = -5.0;
Console.WriteLine(str, x, Math.Sign(x));
Console.WriteLine(str, y, Math.Sign(y));
Console.WriteLine(str, z, Math.Sign(z));
Output:
The sign of 5 is +1
The sign of 0 is 0
The sign of -5 is -1
2.3.6 Angular Units of Measurement
In order to provide a more thorough coverage of both the trigonometric and the hyperbolic functions, it is important to first review the various angular units of mea-
© 2010 by Taylor and Francis Group, LLC
The .NET Framework Math Class Library
79
surement that are available for use and, in addition, to also provide routines in C# for
converting values back and forth between them.
In elementary plane geometry, an angle is formally defined by two rays that intersect at the same endpoint. The point where the two rays intersect is called the
vertex of the angle and the two rays themselves are called the sides of the angle. An
arbitrary angle, say θ , is then measured by first drawing a circular arc of length, say
s, that is centered at the vertex of the angle such that it intersects both of its sides.
Then the length of the arc s is divided by the radius r of the corresponding circle so
that the angle θ = s/r. Since they are defined as the ratio of lengths, angles are considered dimensionless. Nevertheless, there are several units used to measure angles,
the most common of which are the the radian and the degree.
The angle subtended at the center of a circle by an arc that is equal in length to
the radius of the circle is defined to be one radian. The degree, denoted by a small
superscript circle (◦ ) is 1/360 of a full circle. Therefore, one full circle is 360◦ or
2π radians, and one radian is 180◦ /π degrees, or about 57.2958◦. The radian is the
preferred unit of angular measurement in the metric system and is abbreviated rad.
However, this symbol is often omitted in the literature because the radian is assumed
to be the default unit for angle measurement unless specifically stated otherwise. All
the trigonometric methods in the .NET Framework Math Class Library use the radian
as their default unit for angle measurement. The mathematical relationship between
radians and degrees is:
radians = (π /180) ∗ degrees
and
degrees = (180/π ) ∗ radians
The corresponding conversion routines between degrees and radians is given by:
public static double ConvertDegreesToRadians(double degrees)
{
double radians = (Math.PI / 180.0) * degrees;
return (radians);
}
public static double ConvertRadiansToDegrees(double radians)
{
double degrees = (180.0 / Math.PI) * radians;
return (degrees);
}
A sign convention that has been universally adopted in mathematics is that angles
are positive if measured anti-clockwise, and negative if measured clockwise, from
a given reference line. If no line is specified, the reference line can be assumed to
be the x-axis in the Cartesian plane. Fractions of a degree may be written in normal
decimal notation, such as 2.523◦, or in the degree-minute-second unit system. The
minute of arc, also known as MOA, arcminute, or just minute, is 1/60 of a degree
and is denoted by a single prime ( ) or the letter “M”. The second of arc, also known
as arcsecond, or second is 1/60 of a minute of arc or 1/3600 of a degree. It is
denoted by a double prime ( ) or the letter “S”. The following routine illustrates
how to convert an angle expressed in the DMS (degree-minute-second) format to its
corresponding value in the DD (Degree-Decimal) format.
© 2010 by Taylor and Francis Group, LLC
80
Numerical Methods, Algorithms and Tools in C#
public static double DMStoDD(double DMSDeg, double DMSMin, double
DMSSec)
{
double DD = DMSDeg + (DMSMin/60.0) + (DMSSec/3600.0);
return DD;
}
Similarly, the following routine illustrates how to convert an angle expressed in
the DD (Degree-Decimal) format to its corresponding value in the DMS (DegreeMinute-Second) format. Two potential outputs are given: one in the degree/minute/second format and another in the traditional format of xx◦ xx xx .
public static void DDtoDMS(double DD, out double d,
out double m, out double s, out string strDMS)
{
//Extract the degree component
double deg = Math.Floor(DD);
DD -= deg;
DD *= 60;
//Extract the minute component
double min = Math.Floor(DD);
DD -= min;
DD *= 60;
//Extract the second component
double sec = Math.Round(DD);
d = deg;
m = min;
s = sec;
//Create padding character
char pad;
char.TryParse("0", out pad);
//Create degree/minute/second strings
string str_deg = deg.ToString();
string str_min = min.ToString().PadLeft(2, pad);
string str_sec = sec.ToString().PadLeft(2, pad);
//Append degree/minute/second strings together
strDMS = string.Format("{0}\xb0 {1}’ {2}\"", str_deg, str_min,
str_sec);
}
The grad is another unit of angular measurement in the metric system. However,
it is not widely used. The international standard symbol for this unit today is gon.
Other symbols used in the past include ”gr”, ”grd”, and ”g”, the latter sometimes
written as a superscript such as in 50g . The grad is a unit of plane angle, equivalent to
1/400 of a full circle and so one full circle is the equivalent of 400 grads. Therefore,
one grad equals 9/10 of a degree or π /200 of a radian. The following code snippet
contains routines in C# to convert between grads and degrees along with grads and
radians.
© 2010 by Taylor and Francis Group, LLC
The .NET Framework Math Class Library
81
public static double GradsToRadians(double grads)
{
double radians = (grads / 200.0) * Math.PI;
return (radians);
}
public static double RadiansToGrads(double radians)
{
double grads = (radians / Math.PI) * 200.0;
return (grads);
}
public static double DegreesToGrads(double degrees)
{
double grads = (degrees / 9.0) * 10.0;
return (grads);
}
public static double GradsToDegrees(double grads)
{
double degrees = (grads / 10.0) * 9.0;
return (degrees);
}
2.3.7 The Trigonometric Functions
The .NET Framework Math Class Library provides three methods for calculating the
basic three trigonometric functions: cos x, sin x and tan x. These methods are declared
internally as:
public static double Cos(double x);
public static double Sin(double x);
public static double Tan(double x);
The input parameter x must be in radians and is of type double. The output value
returned is the result calculated by the particular trigonometric function and is also
of type double. Similar methods for doing corresponding calculations using complex
numbers will be discussed in a later chapter. The other three remaining trigonometric functions, sec x, csc x and cot x, can be easily calculated from their standard
definitions as shown below:
sec x =
1
cos x
csc x =
1
sin x
cot x =
1
tan x
The domain and range of these six trigonometric functions are summarized in Table
2-1. Note that if x = NaN, NegativeInfinity or PositiveInfinity then these
methods will return NaN instead of throwing an exception. The following code snippet illustrates the use of all six trigonometric functions:
public static double Sec(double x)
{
return (1.0 / Math.Cos(x));
}
© 2010 by Taylor and Francis Group, LLC
82
Numerical Methods, Algorithms and Tools in C#
TABLE 2.1
Domain and Range of the Trigonometric Functions
Function Domain
Range
cos x
−∞ < x < +∞
−1 ≤ cos x ≤ +1
sin x
−∞ < x < +∞
−1 ≤ sin x ≤ +1
tan x
−∞ < x < +∞ except
x = ±π /2, ±3π /2 . . . −∞ < tan x < +∞
sec x
−∞ < x < +∞ except −∞ < sec x ≤ −1 and
x = ±π /2, ±3π /2 . . . 1 ≤ sec x < +∞
csc x
−∞ < x < +∞ except −∞ < csc x ≤ −1 and
x = 0, ±π , ±2π . . .
1 ≤ csc x < +∞
cot x
−∞ < x < +∞ except
−∞ < cot x < +∞
x = 0, ±π , ±2π . . .
public static double Csc(double x)
{
return (1.0 / Math.Sin(x));
}
public static double Cot(double x)
{
return (Math.Cos(x) / Math.Sin(x));
}
public static void TrigFunctions_Example()
{
for (double angleDEG=0.0; angleDEG<=360.0; angleDEG +=45.0)
{
double angleRAD = DegreesToRadians(angleDEG);
Console.WriteLine("Angle = {0}\xb0", angleDEG);
Console.WriteLine("cos({0}\xb0) = {1}",
angleDEG, Math.Cos(angleRAD));
Console.WriteLine("sin({0}\xb0) = {1}",
angleDEG, Math.Sin(angleRAD));
Console.WriteLine("tan({0}\xb0) = {1}",
angleDEG, Math.Tan(angleRAD));
Console.WriteLine("sec({0}\xb0) = {1}",
angleDEG, Sec(angleRAD));
Console.WriteLine("csc({0}\xb0) = {1}",
angleDEG, Csc(angleRAD));
Console.WriteLine("cot({0}\xb0) = {1}",
angleDEG, Cot(angleRAD));
}
}
2.3.8 The Inverse Trigonometric Functions
The .NET Framework Math Class Library provides three methods, ACos x, ASin x,
and ATan x, for calculating the corresponding inverses of the three basic trigonomet-
© 2010 by Taylor and Francis Group, LLC
The .NET Framework Math Class Library
83
ric functions that were just discussed. These methods are declared internally as:
public static double ACos(double x);
public static double ASin(double x);
public static double ATan(double x);
The other three remaining inverse trigonometric functions, ASec x, ACsc x and
ACot x, can be easily calculated from the ones provided by the .NET Framework
Math Class Library by taking advantage of some well known trigonometric identities [18] as shown below:
1
ASec x = ACos ( )
x
1
ACsc x = ASin ( )
x
1
ACot x = ATan ( )
x
The input parameter, x, and the values returned by these methods are all of type
double. However, because of the nature of these inverse functions, their domain and
range values have changed from those given in Table 2-1 and are now summarized
below.
Method: Math.ACos(x)
Input Parameter: A number x of type double such that −1 ≤ x ≤ 1 which represents
the cosine of an angle.
Return Value: An angle θ , measured in radians, such that 0 ≤ θ ≤ π and whose
cosine is the specified number x. If x < −1 or x > 1 then this method returns NaN
instead of throwing an exception.
Method: Math.ASin(x)
Input Parameter: A number x of type double such that −1 ≤ x ≤ 1 which represents
the sine of an angle.
Return Value: An angle θ , measured in radians, such that −π /2 ≤ θ ≤ π /2 and
whose sine is the specified number x. If x < −1 or x > 1 then this method returns
NaN instead of throwing an exception.
Method: Math.ATan(x)
Input Parameter: A number x of type double such that −∞ < x < +∞ which represents the tangent of an angle.
Return Value: An angle θ , measured in radians, such that −π /2 ≤ θ ≤ π /2 and
whose tangent is the specified number x. If x = NaN then this method returns a NaN
instead of throwing an exception. If x = −π /2, rounded to double precision, then
this method returns a NegativeInfinity. If x = +π /2, rounded to double precision,
then this method returns a PositiveInfinity.
Unfortunately, the one-argument arctangent function, ATan(x), does not distinguish between diametrically opposite directions thus making the actual angle that
it finds rather ambiguous. As a result, the .NET Framework Math Class Library
also provides a special two-argument method, called ATan2(y,x), for calculating the
arctangent function which takes into account the sign of the coordinate point (x, y)
© 2010 by Taylor and Francis Group, LLC
84
Numerical Methods, Algorithms and Tools in C#
relative to the origin and places the angle in the correct quadrant. This means that
ATan2(y,x) effectively calculates the counterclockwise angle in radians between the
x-axis and the point (x, y) in a 2-dimensional Cartesian plane. The positive sign is for
counter-clockwise angles (upper half-plane, y > 0), and negative sign is for clockwise angles (lower half-plane, y < 0). Mathematically, the ATan2(y,x) method can
be derived from the ATan(x) by the following formula:
⎧
arctan( yx )
⎪
⎪
⎪
⎪
y
⎪
⎪
⎪arctan( x ) + π
⎪
⎨arctan( y ) − π
x
ATan2(y, x) =
⎪ π2
⎪
⎪
⎪
⎪− π
⎪
⎪
2
⎪
⎩
undefined
x>0
y ≥ 0, x < 0
y < 0, x < 0
.
y > 0, x = 0
y < 0, x = 0
y = 0, x = 0
The ATan2(y,x) method provided by the .NET Framework Math Class Library is
declared internally as:
public static double ATan2(double y, double x);
Alternatively, one can also directly program the mathematical formula for ATan2(y, x)
that was just described calling it, say ATan2A(y, x), as follows:
public static double ATan2A(double y, double x)
{
if (x == 0.0)
{
if (y == 0.0) return double.NaN;
else return (Math.Sign(y) * (Math.PI/2.0));
}
else if (x < 0.0)
{
if (y < 0.0) return (-Math.PI + Math.Atan(y/x));
else return (Math.PI + Math.Atan(y/x));
}
else return (Math.Atan(y / x));
}
Regardless of the choice made, the domain and range of the ATan2(y,x) method is
summarized below.
Method: Math.ATan2(y,x) or ATan2A(y,x)
Input Parameter: The (x, y) coordinates of a point relative to the origin of a Cartesian
plane.
Return Value: An angle θ , measured in radians, such that −π ≤ θ ≤ π , and tan θ =
y/x, where (x, y) is a point in the Cartesian plane. That is, the return value is the angle in the Cartesian plane formed by the x-axis, and a vector starting from the origin,
(0,0), and terminating at the point, (x,y) on the plane. Also,
• For (x, y) in quadrant 1, 0 < θ < π /2.
© 2010 by Taylor and Francis Group, LLC
The .NET Framework Math Class Library
85
• For (x, y) in quadrant 2, π /2 < θ < π .
• For (x, y) in quadrant 3, −π < θ < −π /2.
• For (x, y) in quadrant 4, −π /2 < θ < 0.
For points on the boundaries of the quadrants, the return value is the following:
• If y = 0 and x > 0, θ = 0.
• If y = 0 and x < 0, θ = π .
• If y > 0 and x = 0, θ = π /2.
• If y < 0 and x = 0, θ = −π /2.
As an aside observation, both the inverse functions ASin(x) and ACos(x) can also
be alternately expressed and programmed in terms of the inverse tangent function by
the trigonometric identities:
⎧
π
⎪
x= 1
⎪
⎨ 2
π
x = −1
ASin2(x) = − 2
⎪
x
⎪
√
⎩arctan(
)
−1 < x < 1
2
1−x
public static double ASin2(double x)
{
if (x == 1.0) return (Math.PI/2.0);
else if (x == -1.0) return (-Math.PI/2.0);
else return (Math.Atan(x/Math.Sqrt(1.0-x*x)));
}
⎧
⎪
⎪
⎨0
ACos2(x) = π
⎪
⎪
⎩ π2 − arctan( √ x
1−x2
)
x= 1
x = −1
−1 < x < 1
public static double ACos2(double x)
{
if (x == 1.0) return 0.0;
else if (x == -1.0) return Math.PI;
else return ((Math.PI/2.0)-Math.Atan(x/Math.Sqrt(1.0-x*x)));
}
Finally, the following code snippet shows one way to implement the remaining three
inverse trigonometric functions that were not provided by the .NET Framework Math
Class Library:
© 2010 by Taylor and Francis Group, LLC