|
2 | 2 | #include <stdlib.h>
|
3 | 3 | #include <string.h>
|
4 | 4 |
|
5 |
| -int checkTwoFive(int num){//checks if the number is in 2^a * 5^b form |
6 |
| - while(num%5==0 && num>0){//divides until can no more be divided |
7 |
| - num /= 5; |
8 |
| - } |
9 |
| - while(num%2==0 && num>0){//divides until can no more be divided |
10 |
| - num /= 2; |
11 |
| - } |
12 |
| - return (num==1 ? 1: 0); //1 if valid, 0 if not |
| 5 | +//checks if the number is in 2^a * 5^b form |
| 6 | +int checkTwoFive(int num) { |
| 7 | + while (num % 5 == 0 && num > 0) { //divides until can no more be divided |
| 8 | + num /= 5; |
| 9 | + } |
| 10 | + while (num % 2 == 0 && num > 0) { //divides until can no more be divided |
| 11 | + num /= 2; |
| 12 | + } |
| 13 | + return (num == 1 ? 1 : 0); //1 if valid, 0 if not |
13 | 14 | }
|
14 | 15 |
|
15 |
| -int lengthOfRepetition(int n){ //finds the length of the repetition |
16 |
| - int value=1 ,length=0; |
17 |
| - while(n%2==0 && n>0){ |
18 |
| - n /= 2; |
19 |
| - } |
20 |
| - while(n%5==0 && n>0){//makes sure not divisable by 2 or 5 |
21 |
| - n /= 5; |
22 |
| - } |
23 |
| - |
24 |
| - do{ |
25 |
| - value = value *10; |
26 |
| - value = value % n; |
27 |
| - length++; |
28 |
| - }while (value != 1); //checks after how many steps 'value' returns to what it started as |
| 16 | +//finds the length of the repetition |
| 17 | +int lengthOfRepetition(int n) { |
| 18 | + int value = 1, length = 0; |
| 19 | + while (n % 2 == 0 && n > 0) { |
| 20 | + n /= 2; |
| 21 | + } |
| 22 | + while (n % 5 == 0 && n > 0) { //makes sure not divisable by 2 or 5 |
| 23 | + n /= 5; |
| 24 | + } |
| 25 | + |
| 26 | + do { |
| 27 | + value = value * 10; |
| 28 | + value = value % n; |
| 29 | + length++; |
| 30 | + } while (value != 1); //checks after how many steps 'value' returns to what it started as |
29 | 31 | return length;
|
30 | 32 | }
|
31 | 33 |
|
32 |
| -void Cosimplify(unsigned long *fraction){ //simply den and num until they are co-primes |
33 |
| - for(int i=2;i<=fraction[0]/2;i++){ //fraction[0] is the numerator. assume that den is always bigger |
34 |
| - while(fraction[0]%i==0 && fraction[1]%i==0){ |
35 |
| - fraction[0] /= i; |
36 |
| - fraction[1] /= i; |
37 |
| - } |
38 |
| - } |
| 34 | +void Cosimplify(unsigned long *fraction) { //simply den and num until they are co-primes |
| 35 | + for (int i = 2; i <= fraction[0] / 2; i++) { //fraction[0] is the numerator. assume that den is always bigger |
| 36 | + while (fraction[0] % i == 0 && fraction[1] % i == 0) { |
| 37 | + fraction[0] /= i; |
| 38 | + fraction[1] /= i; |
| 39 | + } |
| 40 | + } |
39 | 41 | }
|
40 | 42 |
|
41 |
| -int findRepetition(char *number, int lenRep){//takes the decimal point string and length of repetition as input. returns the index the repetition starts |
42 |
| - int match;//stores number of same chars |
43 |
| - for(int i=0;i<lenRep*3;i++){ //because of the dot character, non-decimal points will never be mistaken |
44 |
| - match=0; |
45 |
| - for(int j=0;j<lenRep;j++){//check the series for each digit |
46 |
| - if(number[i+j]==number[i+j+lenRep]){ //check if repeats |
47 |
| - match++; |
48 |
| - } |
49 |
| - } |
50 |
| - if(match==lenRep){//if all the repeating digits were present. |
51 |
| - return i; //return the index repetition starts |
52 |
| - } |
53 |
| - } |
54 |
| - return -1; //there is a problem (no repetition?) |
| 43 | +//takes the decimal point string and length of repetition as input. returns the index the repetition starts |
| 44 | +int findRepetition(char *number, int lenRep) { |
| 45 | + int match; //stores number of same chars |
| 46 | + for (int i = 0; i < lenRep * 3; i++) { //because of the dot character, non-decimal points will never be mistaken |
| 47 | + match = 0; |
| 48 | + for (int j = 0; j < lenRep; j++) { //check the series for each digit |
| 49 | + if (number[i + j] == number[i + j + lenRep]) { //check if repeats |
| 50 | + match++; |
| 51 | + } |
| 52 | + } |
| 53 | + if (match == lenRep) { //if all the repeating digits were present. |
| 54 | + return i; //return the index repetition starts |
| 55 | + } |
| 56 | + } |
| 57 | + return -1; //there is a problem (no repetition?) |
55 | 58 | }
|
56 | 59 |
|
57 |
| -int makeDenBigger(unsigned long *fraction){//if the num is bigger than den |
58 |
| - int nonDecimal = fraction[0]/fraction[1]; |
59 |
| - fraction[0] %= fraction[1]; |
60 |
| - return nonDecimal; |
| 60 | +int makeDenBigger(unsigned long *fraction) { //if the num is bigger than den |
| 61 | + int nonDecimal = fraction[0] / fraction[1]; |
| 62 | + fraction[0] %= fraction[1]; |
| 63 | + return nonDecimal; |
61 | 64 | }
|
62 | 65 |
|
63 |
| -void markRepetition(char *number, int index, int length){//formats the string for printing |
64 |
| - if(index==-1){ //in some cases where length==1, index may not be found. |
65 |
| - index=strlen(number)-1; |
66 |
| - } |
67 |
| - for(int i=length;i>0;i--){ |
68 |
| - number[i+index] = number[i+index-1]; |
69 |
| - } |
70 |
| - number[index] = '['; |
71 |
| - number[length+index+1] = ']'; |
72 |
| - number[length+index+2] = '\0'; //dont read beyond this |
| 66 | +void markRepetition(char *number, int index, int length) { //formats the string for printing |
| 67 | + if (index == -1) { //in some cases where length==1, index may not be found. |
| 68 | + index = strlen(number) - 1; |
| 69 | + } |
| 70 | + for (int i = length; i > 0; i--) { |
| 71 | + number[i + index] = number[i + index - 1]; |
| 72 | + } |
| 73 | + number[index] = '['; |
| 74 | + number[length + index + 1] = ']'; |
| 75 | + number[length + index + 2] = '\0'; //dont read beyond this |
73 | 76 | }
|
74 | 77 |
|
75 |
| -void longDivision(unsigned long *fraction, char* number, int lenRep){//applies long division and puts results in a char array |
76 |
| - |
77 |
| - int remainder = 0,num = fraction[0],den = fraction[1],tracker; |
| 78 | +//applies long division and puts results in a char array |
| 79 | +void longDivision(unsigned long *fraction, char *number, int lenRep) { |
| 80 | + int remainder = 0, num = fraction[0], den = fraction[1], tracker; |
78 | 81 |
|
79 |
| - for(int i=0;i<lenRep*3;i++){ |
80 |
| - tracker=0; |
81 |
| - while(num<den){ |
82 |
| - num *= 10; |
83 |
| - if(tracker){ |
84 |
| - number[i]= 0 + '0'; |
85 |
| - i++; |
86 |
| - } |
87 |
| - tracker++; |
88 |
| - } |
89 |
| - remainder = num %den; |
90 |
| - number[i] = num/den + '0'; |
91 |
| - num = remainder; |
92 |
| - } |
93 |
| - number[lenRep*3] = '\0'; |
| 82 | + for (int i = 0; i < lenRep * 3; i++) { |
| 83 | + tracker = 0; |
| 84 | + while (num < den) { |
| 85 | + num *= 10; |
| 86 | + if (tracker) { |
| 87 | + number[i] = 0 + '0'; |
| 88 | + i++; |
| 89 | + } |
| 90 | + tracker++; |
| 91 | + } |
| 92 | + remainder = num % den; |
| 93 | + number[i] = num / den + '0'; |
| 94 | + num = remainder; |
| 95 | + } |
| 96 | + number[lenRep * 3] = '\0'; |
94 | 97 | }
|
95 | 98 |
|
96 |
| -int main(int argc, char **argv) |
97 |
| -{ |
98 |
| - unsigned long fraction[2]; //to hold num and den |
99 |
| - int nonDecimal =0; //hold the non-decimal part |
100 |
| - int lenRep; //length of repetition |
101 |
| - printf("Please enter the numerator and the denominator respectively seperated by a space\n"); |
102 |
| - scanf("%lu %lu", &fraction[0],&fraction[1]); |
103 |
| - if(fraction[0]>fraction[1]){ //if fraction >1 |
104 |
| - nonDecimal = makeDenBigger(fraction); |
105 |
| - } |
106 |
| - Cosimplify(fraction); //Simplify everything |
107 |
| - if(checkTwoFive(fraction[1])){ //if true, there is no repetition |
108 |
| - printf("%g\n", nonDecimal + (double)fraction[0]/(double)fraction[1]); |
109 |
| - }else{ //there is repetition |
110 |
| - lenRep = lengthOfRepetition(fraction[1]); |
111 |
| - char *number = malloc(lenRep*3*sizeof(char)); //3 times the length of repetition just to be safe |
112 |
| - longDivision(fraction,number,lenRep); |
113 |
| - markRepetition(number,findRepetition(number,lenRep),lenRep); |
114 |
| - printf("%d.%s\n",nonDecimal,number); |
115 |
| - free(number); |
116 |
| - } |
117 |
| - |
118 |
| - return 0; |
| 99 | +int main(int argc, char **argv) { |
| 100 | + unsigned long fraction[2]; //to hold num and den |
| 101 | + int nonDecimal = 0; //hold the non-decimal part |
| 102 | + int lenRep; //length of repetition |
| 103 | + printf("Please enter the numerator and the denominator respectively seperated by a space\n"); |
| 104 | + scanf("%lu %lu", &fraction[0], &fraction[1]); |
| 105 | + if (fraction[0] > fraction[1]) { //if fraction >1 |
| 106 | + nonDecimal = makeDenBigger(fraction); |
| 107 | + } |
| 108 | + Cosimplify(fraction); //simplify everything |
| 109 | + if (checkTwoFive(fraction[1])) { //if true, there is no repetition |
| 110 | + printf("%g\n", nonDecimal + (double) fraction[0] / (double) fraction[1]); |
| 111 | + } else { //there is repetition |
| 112 | + lenRep = lengthOfRepetition(fraction[1]); |
| 113 | + char *number = malloc(lenRep * 3 * sizeof(char)); //3 times the length of repetition just to be safe |
| 114 | + longDivision(fraction, number, lenRep); |
| 115 | + markRepetition(number, findRepetition(number, lenRep), lenRep); |
| 116 | + printf("%d.%s\n", nonDecimal, number); |
| 117 | + free(number); |
| 118 | + } |
| 119 | + return 0; |
119 | 120 | }
|
0 commit comments