数学问题——分数的四则运算

  所谓分数的四则运算是指,给定两个分数的分子和分母,求它们加减乘除的结果。

 

一、 分数的表示和化简

  1. 分数的表示

  对一个分数来说,最简洁的写法就是写成 假分数 的形式。因此可以使用一个结构体来储存这种只有分子和分母的分数:

1 // 分数的表示
2 typedef struct {
3     int up, down;    // 分子,分母 
4 } Fraction; 

 

 

 

  于是就可以定义 Fraction 类型的变量来表示分数,或者定义数组来表示一堆分数。其中需要对这种表示制定三项规则:

    • 使 down 为非负。若分数为负,那么令分子 up 为负即可。
    • 如果该分数恰为 0,那么规定其分子为 0,分母为 1。
    • 分子和分母没有除了 1 之外的公约数    

 

  2. 分数的化简

  分数的化简主要用来使 Fraction 变量满足上述分数表示的三项规则,因此化简步骤也可分成以下三步:

    • 如果分母 down 为负数,那么令分子 up 和分母 down 都变为相反数。
    • 如果分子 up 为 0,那么令分母 down 为 1。
    • 约分:求出分子绝对值与分母绝对值的最大公约数 d,然后令分子分母同时除以 d。    

  代码如下:

 1 // 分数化简
 2 Fraction reduction(Fraction result) {
 3     if(result.down < 0) {    // 分母为负数 
 4         result.up = -result.up;
 5         result.down = -result.down;
 6     }
 7     if(result.up == 0) {    // 分数为 0 
 8         result.down = 1;    
 9     } else {    // 约分 
10         int d = gcd(abs(result.up), abs(result.down));    // 求最大公约数
11         result.up /= d;    // 约分
12         result.down /= d; 
13     } 
14     
15     return result;
16 } 

 

 

 

二、 分数的四则运算

  1.  分数的加法

  对两个分数 f1 和 f2 ,其加法计算公式为

    $ result = \frac{f1.up*f2.down + f2.up*f1.down}{f1.down*f2.down} $

  代码如下:

1 // 分数的加法 
2 Fraction add(Fraction f1, Fraction f2) {
3     Fraction result;
4     result.up = f1.up*f2.down + f2.up*f1.down;    // 结果的分子 
5     result.down = f1.down*f2.down;                 // 结果的分母
6     return  reduction(result);                    // 化简 
7 }

 

 

 

 

  2. 分数的减法

  对两个分数 f1 和 f2,其减法计算公式为

    $ result = \frac{f1.up*f2.down - f2.up*f1.down}{f1.down*f2.down} $

  代码如下:

1 // 分数的减法
2 Fraction minu(Fraction f1, Fraction f2) {
3     Fraction result;
4     result.up = f1.up*f2.down - f2.up*f1.down;    // 结果的分子 
5     result.down = f1.down*f2.down;                 // 结果的分母
6     return  reduction(result);                    // 化简 
7 }

 

 

 

 

  3. 分数的乘法

  对两个分数 f1 和 f2 ,其乘法计算公式为

    $ result = \frac{f1.up*f2.up}{f1.down*f2.down} $

  代码如下:

1 // 分数的乘法
2 Fraction multi(Fraction f1, Fraction f2) {
3     Fraction result;
4     result.up = f1.up*f2.up;                    // 结果的分子 
5     result.down = f1.down*f2.down;                 // 结果的分母
6     return  reduction(result);                    // 化简 
7 }

 

 

 

 

  4. 分数的除法

  对两个分数 f1 和 f2 ,其除法计算公式为

    $ result = \frac{f1.up*f2.down}{f1.down*f2.up} $

  代码如下:

1 // 分数的除法
2 Fraction divide(Fraction f1, Fraction f2) {
3     Fraction result;
4     result.up = f1.up*f2.down;                    // 结果的分子 
5     result.down = f1.down*f2.up;                 // 结果的分母
6     return  reduction(result);                    // 化简 
7 }

  分数有额外注意事项。如果读入的除数为 0,那么应当直接特判输出题目要求的输出语句。只有当除数不为 0 时,才能用上面的函数进行计算。

 

 

三、 分数的输出

  分数的输出根据题目的要求进行,但是大体上有以下几个注意点:

    • 输出分数前,需要先对其进行化简。
    • 如果分数 r 的分母 down 为 1,直接输出分子,而省略分母的输出。
    • 如果分数 r 的分子 up 的绝对值大于分母 down,此时应按带分数的形式输出,即整数部分为 r.up/r.down ,分子部分为 abs(r.up)%r.down,分母部分为 r.down。
    • 以上均不满足按原样输出即可    

  代码如下:

 1 // 分数的输出 
 2 void showResult(Fraction r) {
 3     r = reduction(r);        // 化简
 4     if(r.down == 1) {        // r 为整数 
 5         printf("%lld\n", r.up); 
 6     }  else if(abs(r.up) > r.down) {    // r 为假分数 
 7         printf("%d %d/%d\n", r.up/r.down, abs(r.up)%r.down, r.down); 
 8     } else {
 9         printf("%d/%d\n", r.up, r.down);
10     }
11 }

  为了防止计算时溢出,分子和分母应当使用 long long 型来存储。

 

完整代码如下:

 1 /*
 2     分数的四则运算 
 3 */
 4 
 5 #include <stdio.h>
 6 #include <string.h>
 7 #include <math.h>
 8 #include <stdlib.h>
 9 #include <time.h>
10 
11 // 分数的表示
12 typedef struct {
13     int up, down;    // 分子,分母 
14 } Fraction; 
15 
16 // 欧几里得算法求最大公约数 
17 int gcd(int a, int b) {
18     if(b == 0)    return a;
19     else return gcd(b, a%b);
20 }
21 
22 // 分数化简
23 Fraction reduction(Fraction result) {
24     if(result.down < 0) {    // 分母为负数 
25         result.up = -result.up;
26         result.down = -result.down;
27     }
28     if(result.up == 0) {    // 分数为 0 
29         result.down = 1;    
30     } else {    // 约分 
31         int d = gcd(abs(result.up), abs(result.down));    // 求最大公约数
32         result.up /= d;    // 约分
33         result.down /= d; 
34     } 
35     
36     return result;
37 } 
38 
39 // 分数的加法 
40 Fraction add(Fraction f1, Fraction f2) {
41     Fraction result;
42     result.up = f1.up*f2.down + f2.up*f1.down;    // 结果的分子 
43     result.down = f1.down*f2.down;                 // 结果的分母
44     return  reduction(result);                    // 化简 
45 }
46 
47 // 分数的减法
48 Fraction minu(Fraction f1, Fraction f2) {
49     Fraction result;
50     result.up = f1.up*f2.down - f2.up*f1.down;    // 结果的分子 
51     result.down = f1.down*f2.down;                 // 结果的分母
52     return  reduction(result);                    // 化简 
53 }
54 
55 // 分数的乘法
56 Fraction multi(Fraction f1, Fraction f2) {
57     Fraction result;
58     result.up = f1.up*f2.up;                    // 结果的分子 
59     result.down = f1.down*f2.down;                 // 结果的分母
60     return  reduction(result);                    // 化简 
61 }
62 
63 // 分数的除法
64 Fraction divide(Fraction f1, Fraction f2) {
65     Fraction result;
66     result.up = f1.up*f2.down;                    // 结果的分子 
67     result.down = f1.down*f2.up;                 // 结果的分母
68     return  reduction(result);                    // 化简 
69 }
70 
71 // 分数的输出 
72 void showResult(Fraction r) {
73     r = reduction(r);        // 化简
74     if(r.down == 1) {        // r 为整数 
75         printf("%lld\n", r.up); 
76     }  else if(abs(r.up) > r.down) {    // r 为假分数 
77         printf("%d %d/%d\n", r.up/r.down, abs(r.up)%r.down, r.down); 
78     } else {
79         printf("%d/%d\n", r.up, r.down);
80     }
81 }
82 
83 int main() {
84     Fraction f1,f2;
85     f1.down=2, f1.up=1;
86     f2.down=6, f2.up=2;
87     showResult(f1);                // 1/2
88     showResult(f2);                // 1/3
89     showResult(add(f1,f2));        // 5/6
90     showResult(minu(f1,f2));    // 1/6
91     showResult(multi(f1,f2));    // 1/6
92     showResult(divide(f1,f2));    // 1 1/2
93 
94     return 0;
95 }
分数的四则运算

 

posted @ 2018-01-17 12:43  Just_for_Myself  阅读(1517)  评论(0编辑  收藏  举报