博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分数的四则运算
阅读量:7281 次
发布时间:2019-06-30

本文共 6247 字,大约阅读时间需要 20 分钟。

 如果k属于集合Q,Q={ p/q | p是整数,q是正整数,p与q互质},那么k是有理数,Q是有理数集。

 也就是说,有理数都能表示成分数的形式,下面用分数的四则运算来实现有理数的四则运算。

 首先记几个单词:fraction 分数,denominator 分母,numerator 分子,sign 符号

 下面会用到求最大公约数函数gcd,查看定义

 也会用到可变参数函数,如果不清楚,

 

 首先定义分数结构以及一些需要的宏

1 #define abs(a)         ((a)>=0?(a):-(a))//绝对值 2 #define swap(a,b,type) do{ type t;t=a;a=b;b=t; }while(0)//交换变量 3 #define sgn(a)         ((a)>0?1:((a)<0?-1:0))//符号函数 4  5 typedef long DataType; 6 typedef struct 7 { 8     DataType nume;//分子为整数 9     DataType deno;//分母为正整数10 }Frc;

 两个分数相加,返回和

1 Frc frc_add(Frc *opd1,Frc *opd2) 2 { 3     Frc frc; 4     DataType t; 5     assert(opd1&&opd2); 6     //判断其中的一个分数是否为0  7     if(0==opd1->nume) 8         return *opd2; 9     if(0==opd2->nume)10         return *opd1;11     if(opd1->deno==opd2->deno)//如果分母相等 12     {13         frc.nume=opd1->nume+opd2->nume;14         frc.deno=opd1->deno;15     }16     else//如过分母不同17     {18         frc.nume=opd1->nume*opd2->deno+opd1->deno*opd2->nume;19         frc.deno=opd1->deno*opd2->deno;20     }21     if(0==frc.nume)//如果结果为0 22         return frc;23     //约分 24     t=gcd(abs(frc.nume),frc.deno);25     if(1==t)26         return frc;27     frc.nume/=t;28     frc.deno/=t;29     return frc;30 }

 

 两个分数相减,返回差

1 Frc frc_sub(Frc *opd1,Frc *opd2)2 {3     Frc t;4     assert(opd1&&opd2);5     6     t=*opd2;7     t.nume=-t.nume;8     return frc_add(opd1,&t);9 }

 两个分数相乘,返回积

1 Frc frc_mul(Frc *opd1,Frc *opd2) 2 { 3    Frc frc={
0,1};//规定了分母不能为0 4 DataType t; 5 assert(opd1&&opd2); 6 7 if(0==opd1->nume||0==opd2->nume)//如果其中一个分数为0 8 return frc; 9 frc.nume=opd1->nume*opd2->nume;10 frc.deno=opd1->deno*opd2->deno;11 12 t=gcd(abs(frc.nume),frc.deno);//约分 13 if(1==t)14 return frc;15 frc.nume/=t;16 frc.deno/=t;17 return frc; 18 }

 两个分数相除,返回商

1 Frc frc_div(Frc *opd1,Frc *opd2) 2 { 3     Frc frc={
0,1};//分母规定不能为0 4 int sign; 5 assert(opd1&&opd2); 6 7 if(0==opd2->nume)//如果除数为0 8 exit(1); 9 if(0==opd1->nume)//如果被除数为0 10 return frc;11 12 sign=sgn(opd2->nume);//保存opd2符号 13 frc=*opd2;14 swap(frc.nume,frc.deno,int);15 frc.deno=abs(frc.deno);//保证分母为正 16 frc.nume*=sign;17 return frc_mul(opd1,&frc);18 }

求倒数

Frc frc_inverse(Frc *opd){    Frc frc;    int sign;    assert(opd);        if(0==opd->nume)//分子为0,没有倒数         exit(1);    sign=sgn(opd->nume);//保存符号     frc.nume=opd->deno*sign;    frc.deno=abs(opd->nume);    return frc;}

分数的n次幂,n是整数,返回其n次幂

1 Frc frc_pow(Frc *opd,int n) 2 { 3     int t=n; 4     int sign; 5     Frc frc={
0,1}; 6 assert(opd); 7 8 if(n==0) 9 return frc;10 if(0==opd->nume)11 if(n>0)12 return frc;13 else//0没有负数次方 14 exit(1);15 frc=*opd;16 if(n<0)//如果是负次方 17 frc=frc_inverse(opd);18 if(1!=opd->nume)//分子n次方 19 while(--t)20 frc.nume*=opd->nume;21 if(1!=opd->deno)//分母n次方 22 while(--n)23 frc.deno*=opd->deno;24 return frc;25 }

读入分数,n为要读入分数的个数,...的使用方法和scanf类似,函数返回输入分数的个数

1 int frc_input(int n,...) 2 { 3     int cnt=0; 4     Frc *frc; 5     va_list parg; 6     DataType t; 7      8     va_start(parg,n); 9     while(n--)10     {11         frc=va_arg(parg,Frc*);12         scanf("%d",&frc->nume); 13         if(getchar()=='/')//判断是否需要输入分母 14             scanf("%d",&frc->deno);15         else16             frc->deno=1;17         if(frc->deno==0)//如果分母为0 18             return 0;19         if(frc->deno<0)//如果分母为负 20         {21             frc->nume=-frc->nume;22             frc->deno=abs(frc->deno);23         }24         t=gcd(abs(frc->nume),frc->deno);//约分 25         if(1!=t)26         {27             frc->nume/=t;28             frc->deno/=t;29         }30         cnt++;31     }va_end(parg);32     return cnt;33 }

输出分数,方法和printf类似,用%r输入分数,返回输出分数的个数

1 int frc_print(char *format,...) 2 { 3     int cnt=0;//记录输出了几个分数 4     Frc frc; 5     va_list parg; 6     assert(format); 7      8     va_start(parg,format); 9     while(*format)10     {11         switch(*format)12         {13             case '%':14                 if('%'==*(format+1))//如果是%%,则输出% 15                 {16                     putchar('%');17                     format++;18                 }19                 else if('r'==*(format+1))20                 {21                     frc=va_arg(parg,Frc);22                     printf("%d",frc.nume);23                     if(1!=frc.deno)//判断是否需要输出分母 24                         printf("/%d",frc.deno);25                     cnt++;26                     format++;27                 }28                 else29                     putchar(*format);30                 break;31             default:32                 putchar(*format);33                 break;34         }35         format++;36     }va_end(parg);37     return cnt;38 }

下面是测试程序

#include
#include
#include
#include
int main(int argc,char *argv[]){ int instr; Frc frc1,frc2; head(); while(1) { printf("\ninstruction:"); scanf("%d",&instr); switch(instr) { case 0://退出 goto end_pro;case 1://输入 frc_input(2,&frc1,&frc2); break; case 2://输出 frc_print("frc1 = %r frc2 = %r",frc1,frc2); break; case 3://加 frc_print("%r + %r = %r",frc1,frc2,frc_add(&frc1,&frc2)); break; case 4://减 frc_print("%r - %r = %r",frc1,frc2,frc_sub(&frc1,&frc2)); break; case 5://乘 frc_print("%r * %r = %r",frc1,frc2,frc_mul(&frc1,&frc2)); break; case 6://除 frc_print("%r / %r = %r",frc1,frc2,frc_div(&frc1,&frc2)); break; case 7://倒数 frc_print("inverse %r = %r",frc1,frc_inverse(&frc1)); break; case 8://3次幂 frc_print("(%r)^3=%r",frc1,frc_pow(&frc1,3)); break; case 9: head(); break; default: break; } } end_pro: return 0;}

 

转载于:https://www.cnblogs.com/inori/p/4975897.html

你可能感兴趣的文章
用OC代码认识六大设计原则
查看>>
一线互联网常见的14个Java面试题,你颤抖了吗程序员
查看>>
微信小程序开发教程-从零开始(1)
查看>>
docker
查看>>
把你的程序放到桌面——Android桌面部件Widget
查看>>
《图解HTTP》第3章_HTTP报文内的HTTP信息-思维导图
查看>>
分享一个冷门知识——文本框的选择文本在业务中的应用
查看>>
彻底理解浏览器的跨域
查看>>
1009 说反话 (20 分)
查看>>
Flutter Wrap & Chip
查看>>
包教包会vuex
查看>>
机器学习中的核函数
查看>>
Vue路由自动注入实践
查看>>
类数组转化成数组的方法
查看>>
Android屏幕适配方案
查看>>
使用Databinding轻松快速打造仿携程app筛选控件(二)
查看>>
AppCompatActivity怎么对View做的拦截
查看>>
记b站的一次react尝试
查看>>
Binder IPC
查看>>
mpvue开发小程序
查看>>