[Problem description]: in a computer, using float or double to store decimals cannot be accurate. If you want to get the exact calculation result, it is best to use the fractional form to represent decimal places. A finite decimal or infinite repeating decimal can be converted to a fraction. For example, 0.99100.333 (3) 13 (The number in parentheses indicates the cyclic section ).
[Problem description]: in a computer, using float or double to store decimals cannot be accurate. If you want to get the exact calculation result, it is best to use the fractional form to represent decimal places. A finite decimal or infinite repeating decimal can be converted to a fraction. For example: 0.9 = 9/10 0.333 (3) = 1/3 (the number in the brackets indicates the cycle section) of course
[Problem description ]:
In a computer, using float or double to store decimals cannot obtain exact values. If you want to get the exact calculation result, it is best to use the fractional form to represent decimal places. A finite decimal or infinite repeating decimal can be converted to a fraction. For example:
0.9 = 9/10
0.333 (3) = 1/3 (The number in parentheses indicates a circular section)
Of course, a decimal point can be expressed using several fractional forms. For example:
0.333 (3) = 1/3 = 3/9
Given a finite decimal or infinite repeating decimal number, can you return this decimal number in the form of the smallest denominator score? If the input is a circular decimal point, the circular section is marked with parentheses. Below are some possible input data, such as 0.3, 0.30, 0.3 (000), 0.3333 (3333 ),......
Solution:
To solve this problem, we often start with the simplest situation, because all decimals can be decomposed into an integer and the sum of a pure decimal number, so we can only consider that the number is greater than 0, if the number is less than 1, and the approximate score of the numerator and denominator is not considered for the time being, try to represent it as a score and then perform an approximate score. The decimal number entered in the question, or a finite decimal number.X= 0.A1A2...An, Or an infinite loop decimalX= 0.A1A2...An(B1B2...Bm),XLetters in the expressionA1A2...An,B1B2...BmAll are 0 ~ The number in parentheses (B1B2...Bm) Indicates the loop section. We need to deal with the above two situations.
For finite decimal placesX= 0.A1A2...AnThis problem is relatively simple,XEqual (A1A2...An)/10N.
For infinitely repeating decimal placesX= 0.A1A2...An(B1B2...Bm,The complex part is that there are both non-cyclic and cyclic parts after the decimal point. We can perform the following conversions:
X= 0.A1A2...An(B1B2...Bm)
10N*X=A1A2...An.(B1B2...Bm)
10N*X=A1A2...An+ 0 .(B1B2...Bm)
X= (A1A2...An+ 0 .(B1B2...Bm)/10N
For integerA1A2...AnYou only need to convert the fractional part into the fractional form and add this integer. You can process the following Infinite Loop:
LingY= 0.B1B2...Bm, Then
10M*Y=B1B2...Bm.(B1B2...Bm)
10M*Y=B1B2...Bm+ 0 .(B1B2...Bm)
10M*Y-Y=B1B2...Bm
Y=B1B2...Bm/(10M-1)
SetYSubstituted into the previousXThe equation can be:
X= (A1A2...An+Y)/10N
= (A1A2...An+B1B2...Bm/(10M-1)/10N
= ((A1A2...An) * (10M-1) + (B1B2...Bm)/(10M-1) * 10N)
At this point, we can get a fractional representation of any finite decimal or infinite repeating decimal number, but the denominator is not necessarily the simplest. The next task is to minimize the denominator, that is, it is relatively simple to divide the numerator and denominator. For any scoreA/B, Which can be simplified (A/Gcd (A,B))/(B/Gcd (A,B), Where the Gcd function isAAndBThis involves the algorithm in this book (section 2.7 "the maximum number of common appointments"). There is a clever solution. Please read the specific chapter and I will not repeat it here.
To sum up, first obtain the fractional expression of the decimal number, and then perform the approximate score on the denominator of the numerator to obtain the minimum score of the denominator.
For example, for decimal 0.3 (33), according to the above method, the score can be converted:
0.3 (33)
= (3 * (102-1) + 33)/(102-1) * 10)
= (3*99 + 33)/990
= 1/3
For decimal 0. 285714 (285714), we can also calculate:
0. 285714 (285714)
= (285714 * (106-1) + 285714)/(106-1) * 106)
= (285714*999999 + 285714)/999999000000
= 285714/999999
= 2/7
The following code is provided for simple implementation:
Void Cal (char * str) {char * p = str; char * q = str, * q1 = str; // storage (and) of q and q1 respectively) while (* p! = '\ 0') {if (* p =' (') {q = p;} if (* p =') {q1 = p ;} p ++;} if (q = q1) {cout <"finite decimals" <
For perfection, there are two situations:
1. For decimal places, you do not need to define the array form:
# Include
Using namespace std; long gcd (long a, long B) {if (a <B) {long tmp = a; a = B; B = tmp ;} int I, k = 0; while (B! = 0) {if (a & 1) = 0) {if (B & 1) = 0) {// a, B is an even number, f (a, B) = 2 * f (a> 1, B> 1) a >>= 1; B >>= 1; k ++ ;} else // a is an even number, B is an odd number, f (a, B) = f (a> 1, B) a >>= 1 ;} else {if (B & 1) = 0) // a is an odd number, B is an even number, f (a, B) = f (a, B> 1) b> = 1; else // a, B are odd, f (a, B) = f (a-B, B) a = a-B ;} if (a <B) {long tmp = a; a = B; B = tmp ;}} return a <k ;}int main () {long a = 0, B = 0, c = 0; // integer part c, non-cyclic decimal a, cyclic decimal bscanf ("% d. % d (% d) ", & c, & a, & B); if (a = 0 & B = 0) cout <c; e Lse {// molecular up, denominator downlong long up = c; long down = 1; long ta = a; while (ta) {down * = 10; ta/= 10;} up = c * down + a; if (B! = 0) {long wb = 1; long tb = B; while (tb) {wb * = 10; tb/= 10;} up = up * (wb-1) + B; down = down * (wb-1);} long fac = gcd (up, down ); cout <up/fac <"/" <down/fac <endl ;}}
2. It is used for big integers and defines the big Integer type and corresponding addition, subtraction, multiplication, division, and comparison shift operations.
# Include
# Include
# Include
Using namespace std; // large integer type # define MAXLEN 1000 struct HP {int len, s [MAXLEN] ;}; void PrintHP (HP x) {for (int I = x. len; I> = 1; I --) cout <x. s [I];} // string to a large integer void Str2HP (const char * s, HP & x) {x. len = strlen (s); for (int I = 1; I <= x. len; I ++) x. s [I] = s [x. len-I]-'0'; if (x. len = 0) {x. len = 1; x. s [1] = 0 ;}/// large integer addition void Plus (const HP a, const HP B, HP & c) {int I; c. s [1] = 0; // The addition operation of big integers a and B and the carry operation of Result c for (I = 1; I <=. Len | I <= B. len | c. s [I]; I ++) {if (I <=. len) c. s [I] + =. s [I]; if (I <= B. len) c. s [I] + = B. s [I]; c. s [I + 1] = c. s [I]/10; c. s [I] % = 10;} // The reason for exiting the loop is c. s [I] = 0, so take the previous c. len = I-1; if (c. len = 0) c. len = 1 ;}// subtraction of a large integer void Subtract (const HP a, const HP B, HP & c) {int I, j; for (I = 1, j = 0; I <=. len; I ++) {// j indicates whether to borrow a high position c. s [I] =. s [I]-j; if (I <= B. len) c. s [I]-= B. s [I]; if (c. s [I] <0) {// Add 10j = 1 to the high bid; C. s [I] + = 10;} else j = 0;} c. len = a. len; while (c. len> 1 &&! C. s [c. len]) c. len --;} // compare int HPCompare (const HP & x, const HP & y) {if (x. len> y. len) return 1; if (x. len <y. len) return-1; int I = x. len; while (I> 1 & (x. s [I] = y. s [I]) I --; return x. s [I]-y. s [I];} // multiplication void Multi (const HP a, const HP B, HP & c) {int I, j; // assign an initial value to the multiplication result to facilitate the subsequent + = operation c. len =. len + B. len; for (I = 1; I <= c. len; I ++) c. s [I] = 0; for (I = 1; I <=. len; I ++) for (j = 1; j <= B. len; j ++) c. s [I + J-1] + =. s [I] * B. s [j]; // calculates the result carry for (I = 1; I
1 &&! C. s [I]) I --; c. len = I;} // division of large integers void Divide (const HP a, const HP B, HP & c, HP & d) {int I, j; // use the remainder d to store the first I-bit data of divisor a, and subtract the divisor B multiple times to obtain the commercial cd. len = 1; d. s [1] = 0; for (I =. len; I> 0; I --) {if (! (D. len = 1 & d. s [1] = 0) {// I does not shift one digit, and the remainder d is also shifted for (j = d. len; j> 0; j --) d. s [j + 1] = d. s [j]; d. len ++;} d. s [1] =. s [I]; c. s [I] = 0; // when the remainder d is greater than divisor B, you can perform the while (j = HPCompare (d, B)> = 0) operation) {Subtract (d, B, d); c. s [I] ++; if (j = 0) break ;}} c. len =. len; while (c. len> 1 & c. s [c. len] = 0) c. len --;} // right shift void RightShift (HP & x, int k) {for (int I = 1; I <= x. len-k; I ++) x. s [I] = x. s [I + k]; x. len-= k; if (x. len <= 0) {x. len = 1; x. s [1] = 0 ;}/// decimal left shift void LeftShift (HP & x, int k) {int I; for (I = x. len; I> = 1; I --) x. s [I + k] = x. s [I]; for (I = k; I> = 1; I --) x. s [I] = 0; x. len + = k;} // calculate the maximum approximate number of big integers void GCD (HP a, HP B, HP & c) {if (B. len = 1 & B. s [1] = 0) {c. len =. len; memcpy (c. s,. s, (. len + 1) * sizeof (int);} else {HP m, n; Divide (a, B, m, n); GCD (B, n, c) ;}} int main () {string str; string strc, stra, strb; cin> str; int posc = str. find ('. '); int posa = str. find ('); int posb = str. find ('); strc = str. substr (0, posc); if (posc <0) cout <strc; else {HP a, B, c; HP tmp; tmp. len = 1; tmp. s [1] = 1; // The integer part Str2HP (strc. c_str (), c); stra = str. substr (posc + 1, posa-posc-1); // non-cyclic part Str2HP (stra. c_str (), a); // up molecule, down denominator HP up = c, down = tmp; // multiply by 10 ^ | a | LeftShift (down, stra. size (); LeftShift (up, stra. size (); Plus (up, a, up); if (posa> = 0) {strb = str. substr (posa + 1, posb-posa-1); // loop part Str2HP (strb. c_str (), B); HP m = tmp; LeftShift (m, strb. size (); Subtract (m, tmp, m); // multiply by 10 ^ (| B |-1) Multi (up, m, up); Plus (up, b, up); Multi (down, m, down);} // calculates the maximum common divisor GCD (down, up, tmp); HP h; Divide (down, tmp, down, h); Divide (up, tmp, up, h); PrintHP (up); cout <"/"; PrintHP (down ); cout <endl ;}}