Calculate the E value using a decimal array (answers to the ZOJ 1,113rd question)

Source: Internet
Author: User
Http://acm.zju.edu.cn/show_problem.php? Pid = 1113 is as follows: according to the formula
E = 1/0! + 1/1! + 1/2! + 1/3! +... + 1/n!
Calculate e. The number of decimal places required for the output (9 digits ).
The question is intuitive, and the most intuitive idea is probably a computing n! And then a loop from 0 to n to accumulate all decimals. However, this obviously involves a lot of redundant computing. To avoid this situation, it is clear that,
Suppose a [n] represents 1/n !, E [n] indicates e, then
A [n + 1] = a [n]/(n + 1 );
E [n + 1] = e [n] + a [n + 1];
Based on this equation, we can write a solution. Because decimal precision is required in the question, double may be able to meet the precision as the number of digits in the computer increases. However, 16-bit TC does not seem to be able to meet the requirements. Therefore, we need to use the large number method to process decimal places. That is, an array a [] is used to represent the fractional part. (Here we assume that the decimal point has the form of 0. *********). According to the convention of this processing method, we stipulate that,
A [0] indicates the number of digits in the decimal place. a [I] (I> 0) stores the digits in the decimal place. For example, PI 3.1415926, its decimal part can be represented in the following array:
{, 0 ,........};
This decimal number can be expressed
A [1] * 10 ^ (-1) + a [2] * 10 ^ (-2) +... + a [n] * 10 ^ (-n)
Because
A * 10 ^ (-I) + (10 * B + c) * 10 ^ (-(I + 1) = (a + B) * 10 ^ (-I) + c * 10 ^ (-(I + 1 ))
Therefore, the adjacent bits are carried or deprecated and normalized according to this rule.
Based on the iteration formula above, we can see at least two decimal operations. One is dividing the decimal number by the integer, and the other is adding the two decimal numbers. In fact, the accuracy of this question is not high, so the requirements for code execution efficiency can be reduced, but for general purpose, I still maintain the regular style of this algorithm.
Below is a code dividing a decimal number by an integer. Because a normalized decimal number cannot produce a result greater than 10, we do not need to normalize the result. Dividing a decimal number by an integer
# Define DISLEN 9/* Maximum number of decimal places */
# Define TOTLEN 13/* total length, that is, display the number of decimal places + number of redundant decimal places */
/* Calculate the decimal number of a 0. -- By the decimal number after an integer. */
Void Devide (int a [], int n)
{
Int I, temp;/* remainder */
For (I = 1; I <= a [0] & I <(TOTLEN-1); I ++)
{
Temp = a [I] % n;/* Save the remainder first !!! You cannot change a [I] first. Remember! */
A [I] = a [I]/n;
A [I + 1] + = temp * 10;
If (I = a [0] & temp! = 0)
A [0] = I + 1;
}
/* Perform division operation on the last digit */
A [TOTLEN-1]/= n;
}

As the result needs to be rounded up, I actually provide some percentile bits to ensure that the result is correct.
The following is the code for adding two decimal places, that is, a = a + B. The result is that a is changed to the sum of the two, and B is not changed. Modifications based on a can save space. The code for addition and subtraction of large numbers is relatively simple and intuitive. Add two decimal places
/* Pay attention to the addition of two positive decimal places. Their maximum digits can only be reduced, and they cannot be increased! */
Void Add (int a [], int B [])
{
Int I;
A [0] = MAX (a [0], B [0]);
For (I = 1; I <= a [0]; I ++)
{
A [I] + = B [I];
}
/* Regular decimal number */
Formular ();
}
/* Normalized decimal points after addition */
Void formular (int a [])
{
Int I;
For (I = a [0]; I> 1; I --)
{
A [I-1] + = a [I]/10;
A [I] = a [I] % 10;
}
A [1] = a [1] % 10;

/* When the last digit is 0, the number of digits decreases (the number of digits is reduced )*/
While (! A [a [0] & a [0])
{
A [0] --;
}
}

Note: After adding two decimal places, the result may be greater than 10 digits. Therefore, a regular operation is required.
Finally, we also need to scan the array and output the result after rounding: because our purpose is to calculate e, the integer part is the "2 .". Output result value after rounding
/* Output the decimal number of e, starting with 2. e [] is the decimal part */
Void OutputE (int a [])
{
/* Len indicates the decimal length after rounding, and flag indicates whether to carry! */
Int I, len, flag;
Printf ("2 .");
/* Round the last digit! If the number of digits is not greater than DISLEN, No rounding is required */

Len = DISLEN + 1;
If (a [len]> 4)
{
Flag = 1;
While (a [-- len] = 9 );
}
Else
{
Flag = 0;
While (a [-- len] = 0 );
}

/* Print the first few characters */
For (I = 1; I <len; I ++)
Printf ("% d", a [I]);
/* Print the last digit based on whether it is carried */
If (len> 0)
Printf ("% d", flag? (A [len] + 1): a [len]);
For (I = len + 1; I <= DISLEN; I ++)
Printf ("0 ");
Printf ("\ n ");
}

Finally, we provide the code for the iteration part. Because the iteration type is used, the next calculation is based on the calculation result of the previous step, thus avoiding redundant calculation. Result of iteration E
Int e [TOTLEN], a [TOTLEN];
/* E2 = 2.5, a2 = 0.5 */
E [0] = a [0] = 1;
E [1] = a [1] = 5;

For (j = 3; j <= 9; j ++)
{
Devide (a, j);/* a [n + 1] = a [n]/(n + 1 );*/
Add (e, a);/* e [n + 1] = e [n] + a [n + 1]; */
Printf ("% d", j );
OutputE (e );
}

When we want to output 80 decimal places, the result is as follows (the internal data type that can be directly computed cannot achieve this precision ):
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.