27-07-2012, 11:36 AM
Scientific Calculator
Main Codes Will Use
• Class
• Inheritance
• Constructor
• Destructor
• Function
• Inline Function
• Static Function
The calculator is an extension of a mathematician and it has opened up new possibilities
within mathematics. It is a machine though, and it is only capable of doing what it is
programmed to do. Accordingly, this project aims to develop the internal programmed
computational code in the form of a computer program that a scientific calculator could use to
compute functions such as square root, the exponential, and sine functions.1 The idea of this
project assumes that that the programmer has already developed the very basic addition,
subtraction, multiplication, division and integer splicing2 functions. Then using these basic
functions, the program will then compute other more complicated functions found on a typical
scientific calculator such as the sine and logarithmic functions.
With the necessity to conform to reality, there are limitations set upon this calculator and
they are similar to those found in popular calculators such as the Texas Instruments TI-83 Plus.
They are that:
(1) functions inputs and outputs must be calculated accurately to ten significant figures3,
(2) the absolute values of inputs and outputs, excluding zero, can never be greater than or equal
to 1 x 10100 or less than or equal to 1 x 10-100.
Similar to these mandatory requirements, there are a few goals that I wish to accomplish within
the confines of the limitations. They are that:
(1) the code is as easily programmed as possible,
(2) and that the program is to be as efficient as possible at computing the functions.
Every programming language has advantages and disadvantages; because I was familiar
with the C++ programming language and learning a new language was beyond the scope of this
project, I chose to work within the C++ language. A few advantages with choosing this
language are that the code is easily transferred into other programming languages and that it is
universally known. I choose to use a Windows Console application due to its simplicity and my
familiarity with it, but this is a disadvantage because it is not an optimal interface for a
calculator due to its lack of visual resemblance of a handheld calculator.
The interface created for user inputs and outputs was created for basic test purposes only,
and if I had more time, I would have liked to use Visual Basic to create a visual calculator with
buttons that were able to be pressed. Even though the created interface looks rudimentary, it
contains all the possible tasks that the program is able to do. There were other programming
and computations issues that needed to be taken into account as well when transferring
mathematical theory into a working calculator. One issue was the large difference in
computational time. Computing multiplication and division takes significantly longer time than
computing addition and subtraction, and therefore should be avoided whenever possible. Thus
throughout the program there are instances where addition and subtraction is used to eliminate
the need for multiplication. Another issue is that the program is constantly rounding numbers
and thus losing trailing digits. Therefore in some cases it is very difficult or impossible to
adhere to the goals previously described. An example of this is within the modulo function
which cannot be evaluated for relatively large values modulo a relatively small value.
Methods of Approximation
It is unnecessary to get exact values for the results of many of the functions because they
are either irrational (and thus it’s impossible) or they are contain more digits than necessary to
obtain the required 10 significant figures accuracy. Therefore, instead of attempting to get the
exact value of a function, the goal of this calculator is to get 10 significant figure
approximations of a function for a given input as stated previously. To approximate the
functions, while conforming to the limitations of addition, subtraction, multiplication, and
division, there are many different possible methods.
There are a few methods used frequently throughout the program. The first method is to
take advantage of identities wherever possible such as xy = x y . There are typically a few
identities used in every approximation. Next is to use encode exact answers into the code
wherever it is felt appropriate. An example of this is “hard coding” the natural log of one to be
zero.
Thirdly is to use a polynomial equivalent to:
To obtain the variable values in expression (i) the first method that was attempted is
called the discrete least squares method. If “Approx(x)” is the approximating polynomial and
“Function(x)” is the function being estimated, this method minimizes:
(Approx(k) Function(k))2 .
for a discrete set of chosen points, k. In minimizing this, the ak terms of (i) are then found and
used to generate a best-fit polynomial of a degree preset by the user. While this method works,
for the purposes of this project, it is not ideal because it does not calculate for an entire interval,
rather only finite number of points. Therefore it was disregarded in search of a method that will
calculate along intervals and for a specific set of values.
The next method found was the continuous least squares method and it is very similar to
the discrete least squares method, but it calculates along intervals. This method minimizes the
integral:
(Approx x Function x)dx
Upper Bound
LowerBound
∫ () − ( ) 2 ,
to determine the best approximation polynomial for an interval of a predetermined user defined
degree. This method is far better than the discrete least squares method at approximating
intervals, but there exists an adaptation of this idea that is even more accurate for specifically
estimating polynomials such as those used in this program called the Chebyshev least squares
approximation method.
The Square Root Function (Sqrt(x))
The square root function is a necessary part of this calculator because it will be used in
the estimation of the Arc Sine function, among others described later, as well as it is a commonly
used function that is useful operation on a calculator. The calculation of this function involves a
few different identities, some hard coded values, and then an estimation polynomial. For the
purposes of this calculator the square root function’s domain is{0} ∪ (10−100 ,10100 ).
For the values of x equal to zero and one, it is hard coded into the program that the square
root of x is equal to zero and one respectively. For values of x in the interval (0, 1), the identity
x = 1 / 1/ x is used to convert the values that will be computed into the set (1, 10100) because
of the reciprocal of a number in the interval (10-100, 1) is in the interval (1, 10100).
Therefore it is only necessary to estimate the function for values of x contained in (1,
10100). Estimating the interval of the square root function from 1 to 10100 requires a very high
degree polynomial to obtain the required ten significant figures accuracy. This high degree
polynomial would require many computations of multiplication and be very time consuming for
the processor to compute. Therefore to avoid this and make the process for efficient to compute,
first the estimation will make use the identity
xy = x y .
Using this, it is possible to break down large numbers into smaller ones that make the estimation
easier to compute because it makes the required estimation interval smaller. Given any value of
x in [1050, 10100), the square root can be computed by the formula:
x = 1050 x /1050 =1025 x /1050 .
Thus, the square root of x in the interval [1050, 10100) would now be 1025 (a constant) times the
square root of x / 1050, and x / 1050 is contained in the interval [1, 1050). Continuing this method
of breaking down values of x, we can make the polynomial estimation interval of the square root
function relatively small. Continuing along this principle of breaking down the interval, the next
few intervals would be
[1,1025 ),[1,1012.5 ),[1,106.25 ),[1,103.125 ), . . .
This can continue into infinitely small intervals, but at a cost of one division and one
multiplication per break down. Therefore it becomes necessary to determine when to stop this
process. For this function it was determined that the ideal time to stop was for values of x in the
interval (1, 1.0578255745 ].6 Therefore the interval of values (1,1.0578255745] is the only
interval of the square root function that has yet to be estimated. To estimate this interval, a
fourth degree polynomial is used to obtain the required accuracy, and with this, the entire square
root function can be computed.
The Power Function (X^Y)
The power function is an easy function to compute using an identity based upon the
logarithmic and exponential functions that will be discussed later. The basic idea that it uses is
the identity
x y = exp(y *ln(x)) .
The only issue that needs to be dealt with is that this identity is only defined for positive values
of x, but the power function is also defined for x values of{0}∪ (−10100 , −10−100 ). Therefore to
deal with the first part of this set, it is hard coded that if x = 0, then the result equals 0 as long as
y does not equal zero as well. If x = y = 0, then an error is reported.
If x is in the interval (−10100 , −10−100 ) then x is negated and then the equation needs to be
adjusted. To adjust it we must deal with the problem that only integer values of y return a real
valued solution if x is in the interval (−10100 , −10−100 ). Therefore, the function will first abort if
there would be a complex result, and then it will determine if the answer should be positive or
negative. To do this, it uses the Modulo Estimator Function that will be discussed shortly, and
determines if the y value is an odd number, and if is, it will negate the result.
Therefore the Power Function is based almost entirely on other functions and is easy to
code. This does have its downfalls though, first it that it relies heavily on the natural logarithmic
function and the exponential function. Thus it can only be as efficient and accurate as these
functions are. This is the reason why the square root function was developed separately. While
the square root function takes time to develop and space in the memory, it is, on average,
significantly more efficient than the powers function at computing the square root of a number,
and because it is commonly used and a necessary computation in other functions, it was
determined that it was worth the time and memory space.
Trigonometry Functions - Modulo
The first function that needs to be addressed in order to be able to compute trigonometric
functions is the modulo function. It is a very important function because used in the sine, cosine,
tangent functions and others throughout the program. The first thing that needs to be dealt with
in the modulo function as developed here is non-positive values of y, if we write the function x
(mod y). In this program, this is not valid, and thus will return an error.
Following this detail, the program uses the idea that if x is positive or zero
x (mod y) = y
Therefore if this result is greater than or equal to
zero, it only needs to be multiplied by y to find the final result to return, if it is negative, then one
is added to it and then multiplied by y to find the final result to return.
There are limitations on this due to the necessity of having remainders. For large values
of x, and small values of y > 0, the computer is unable to store enough significant figures to
compute the remainder accurately.
Sine Function (Sin(x))
The sine function’s symmetry makes this function easy to compute. The first thing that is
done is that x is converted by the equation x = x (mod (2π)). This immediately changes the
interval that needs to be estimated into the interval [0, 2π). To this symmetry is exploited even
further using the identities:
1.) if x is in the interval (π/2, π], then sin(x) = sin(π – x),
2.) if x is in the interval (π, 3π/2], then sin(x) = -sin(x – π), and
3.) if x is in the interval (3π/2, 2π), then sin(x) = -sin(2π – x).
Therefore it is only necessary to compute sine on the interval [0, π/2]. To estimate this interval,
polynomial approximations of sine will be used. This interval is then broken up into three
smaller intervals for accuracy reasons, and then three polynomials are used to compute sine.
The only non-basic exterior function that sine calls upon is the modulo function which is
unable, due to round off error, to compute large numbers modulo 2π. Accordingly sine adheres
to the limits of the modulo function and for this reason, the sine function cannot be computed
accurately or at all if the absolute value of the computed number is large.
Cosine and Tangent Functions (Cos(x) and Tan(x))
The cosine and tangent functions are largely based on the sine function. For cosine, the
computation is easy, cos(x) = sin(x – π/2), and thus this is exactly what the program computes.
The tangent function uses the identity
cos( )
tan( ) sin( )
x = x for computation. With tangent though,
there is one trick used for efficiency, in an effort to reduce redundancy and unnecessary
computations, before the sine and cosine functions are computed, x is standardized into the
interval [0, 2π). Furthermore, after standardization, if x is less than π/2, then the program adds
2π to the value in the cosine function to prevent an unintended second standardization. This
eliminates the need to ever standardize x twice. With this cosine and tangent are complete and as
accurate as the sine function.
Arc Sine (ArcSin(x))
The arc sine function is only real valued for the interval [-1, 1]. To exploit symmetry for
the interval (-1, 0), the identity arcsin(x) = -arcsin(-x) can be used to rely on the interval of (0, 1).
The values {-1, 0, 1} are all hard coded into the program, and thus it only remains to compute
the interval (0, 1). To do this, the interval is reduced further by the identity
( arcsin(x) = − arcsin( 1− x2 ) +π / 2 ).10
Using this, the estimation interval (0, 1) can be further reduced to the estimation interval
(0, 2 . This interval is then broken down into three different intervals for accuracy reasons,
and estimated using polynomial approximations.
Arc Cosine (ArcCos(x))
The arc cosine function is real valued for the interval [-1, 1]. The values {-1, 1} are hard
coded into the program for efficiency, and using the identity
arcos(x) = arcsin(-x) + π/2
the remaining interval is computed.
Arc Tangent (ArcTan(x))
Arc tangent is computed using an identity. Before the identity can be used efficiently,
input values less than -1010 return is –π/2 and similarly if the input value is greater than 1010 then
the returned value is π/2. Following this, the identity
arctan( ) arcsin
is used to determine the arc tangent function on the interval (-1010, 1010).
Exponential Function – (Exp(x))
The exponential function is only defined, based on the constraints of this calculator, for
values of x in the set {0} ∪ (10-100, 230.25850929940) ∪ (-230.25850929940, -10-100). If x is
equal to zero, it is hard coded that the result is one. If x is in the interval less than zero, the
identity:
e − = 1
10 Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables edited by Milton
Abramowiz and Irene A. Stegun, United States Department of Commerce. (Washington D.C.: 1970) Page 82
- 11 -
is used to leave the only interval of estimation necessary to compute being (10-100,
230.25850929940). Using the idea that
ex+ y = exe y ,
this interval can be broken down even further in a similar manner as the square root function. It
was determined that the optimal time to stop this breaking down process is for values of x is in
the interval (0, 0.125). To calculate this smaller interval, an estimating polynomial is used of
degree 4.
Logarithmic Functions – (Ln(x), Log(x) [base 10])
The Log(x) [base 10] is based upon the natural log function. If x is in the interval
(10-100 , 10100 ) then the equation:
Log(x) [Base 10] = Ln(x) / 2.3025850929940
is used. Therefore it is only necessary to calculate the natural log function.
The natural log function is defined for (10-100 , 10100 ) . Hard coding that ln(1) = 0 and
using the identity:
ln(x) ln 1
the estimation interval can be reduced to the interval (1, 10100). To estimate this interval the
identity
ln(x * y) = ln(x) + ln(y)
is used to break down this interval in a similar method as the square root function. From this it is
determined that it is ideal to stop breaking the intervals down is for values of x in the interval
(1,1.0578255745) . To estimate values of x is in this interval, approximating polynomials are
used to obtain an estimation of the function. Therefore, using identities, and then breaking down
the function, it is possible to compute this function on the entire interval.