
پروژه ماشین حساب با عملیات روی اعداد ۱۰۰۰ رقمی با زبان c
امروز با یک برنامه پیچیده تر آمده ایم که جنبه آموزشی بالایی دارد و هدف آن آموزش ایجاد الگوریتم و توابعی برای جمع و تفریق و ضرب اعداد بزرگ تا ۱۰۰۰ رقم است. داستان این برنامه این است که ۴ ماشین حساب داریم و برای هر ماشین حساب یک سری عدد تصادفی صحیح و مثبت حداقل ۱۰۰ رقمی و حداکثر ۱۰۰۰ رقمی تولید می کنیم همچنین به صورت تصادفی یک سری عملگر ایجاد می کنیم و آن ها را به ۴ ماشین حساب می دهیم تا هر ماشین حساب ورودی های خود را پردازش کند.ما زمان پردازش محاسبات را برای هر ماشین حساب در نظر می گیریم و در آخر بر اساس زمان محاسبات آن ها را رتبه بندی می کنیم و در خروجی چاپ می کنیم .فقط توجه داشته باشید الگوریتم محاسبه ماین حساب ها با هم فرق نمی کند تفاوت در اعداد تصادفی است .این برنامه جواب حاصل از هر ماشین حساب را در فایلی به همان اسم قرار می دهد نکته این سوال توابعی برای ضرب جمع و تفریق اعداد با طول بلند و فراخوانی تایم و ایجاد عدد تصادفی با طول زیاد است.
در این نمونه بیشتر سعی شده است که به تابع های جمع و منها و ضرب پرداخته شود به خصوص ضرب چون خیلی ها ضرب را بر اساس جمع های متوالی می نویسند که زمان زیادی را می برد و الگوریتم مناسبی نیست تابع ضرب ما دقیقا همان کاری را می کند که انسان ها می کنند .البته تابع تقسیم در پست بعد نوشته خواهد شد ولی چون از تفریقهای متوالی استفاده شده همیشه سرعت خوبی ندارد پس استفاده نشده.
یکی از سوالات متداول این است که چگونه اعداد تصادفی با طول حداقل ۱۰۰و حداکثر ۱۰۰۰ کاراکتر به وجود بیاوریم .ساده ترین را این است که به صورت تصادفی طول رشته را تعیین کنیم و بعد خانه های رشته را تک تک پر کنیم(ولی این روش درست نیست زیرا تصادفی بودن ۱۰۰% نیست ولی ساده ترین روش است).که این کار را تابع getRandomNumber انجام می دهد.
تابع compare دو رشته را مقایسه می کند و می گوید ارزش کدام از لحاط ریاضی بزرگ تر است.
تابع Sub هم همان تابع تفریق است با نگاه کردن به کد می توانید به الگوریتم آن پی ببرید.
تابع add همان تابع جمع است که الگوریتم ساده ای دارد ولی باید به این نکته توجه شود که وقتی دو عدد ۱۰۰۰ رقمی را باهم جمع می کنید ممکن است عدد ۱۰۰۱ رقمی شود.
تابع big_sum تابع جمع برای اعداد ۲۰۰۰ رقمی است که در function ضرب به کار رفته تا اعداد حاصل شده در آن تابع را جمع نماید.
تابع mul همان تابع ضرب است فقط توجه داشته باشید وقتی دو عدد ۱۰۰۰ رقمی را ضرب می کنید حداکثر عددی که به دست می آید عددی ۲۰۰۰ رقمی است (تابع big_sum برای همین جاست)الگوریتم آن دقیقا مثل روش دستی خودتان برای ضرب کردن است.
نکته دیگر این است که برنامه محاسبات انجام شده توسط هر ماشین حساب را در فایلی به همان نام ذخیره می کند و نکته دیگر آن است که اعداد ذخیره شده در فایل طبق فرمت عدد است یعنی اگر فرمت عدد ۱۰۰۰ رقمی است و جواب ما ۱۵۰ رقمی است سمت چپ عدد ۸۵۰ صفر قرار دارد که از لحاظ ریاضی فرقی نمی کند.
سرعت محاسبات را می توانید در عکس زیر ببینید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <time.h> #include <string.h> //----------------------------------------------------------------- //compare two string and return +1 if x>y return -1 if x<y and return 0 if x=y int compare(char x[1001],char y[1001]) { int i; for(i=0;i<1001;i++) { if(x[i]>y[i]) return 1; if(x[i]<y[i]) return -1; } return 0; } //---------------------------------------------------- //make randomize number void getRandomNumber(char a[1002]) { a[1001]='\0'; int length,i; length=(rand()%900)+100; for(i=0;i<=1000;i++) { a[i]='0'; } for(i=0;i<length;i++) { a[1000-i]=(rand()%10)+48; } i--; if(a[1000-i]=='0') { while(a[1000-i]=='0') { a[1000-i]=(rand()%10)+48; } } } //---------------------------------------------------------------------------------------------------- //sub is function that subtract two char array. void Sub(char x[1002],char y[1002],char cal_name) { FILE *fp; switch(cal_name) { case 'A':fp=fopen("A.txt","a+");break; case 'B':fp=fopen("B.txt","a+");break; case 'C':fp=fopen("C.txt","a+");break; case 'D':fp=fopen("D.txt","a+");break; case 'F':fp=fopen("F.txt","a+");break; } int i,j,temp=0; char z[1002]; z[1001]='\0'; for(i=0;i<=1000;i++) { z[i]='0'; } if(compare(x,y)==-1) { char temp; for(i=0;i<=1001;i++) { temp=y[i]; y[i]=x[i]; x[i]=temp; } } for(i=1000;i>=0;i--) { temp=x[i]-y[i]; if(temp>=0) { z[i]=temp+48; } else { j=i-1; while(x[j]=='0') { x[j]='9'; j--; } x[j]=x[j]-1; z[i]=((x[i]-48)-(y[i]-48)+10)+48; } } fprintf(fp,"%s\n-\n%s\n=\n%s\n\n\n\n",x,y,z); fclose(fp); } //----------------------فرهاد دلیرانی------------------- //Add two-digit numbers to at least 1000 does void add(char a[1002],char b[1002],char cal_name) { FILE *fp; switch(cal_name) { case 'A':fp=fopen("A.txt","a+");break; case 'B':fp=fopen("B.txt","a+");break; case 'C':fp=fopen("C.txt","a+");break; case 'D':fp=fopen("D.txt","a+");break; case 'F':fp=fopen("F.txt","a+");break; } int i,j=1001,l=0,p; char c[1003]; c[1002]='\0'; for(i=0;i<=1000;i++) { c[i]='0'; } for(i=1000;i>=0;i--) { p=((a[i]-48)+(b[i]-48)+l); c[j]=(p%10)+48; if((p<=9)) { l=0; } else { l=1; } j--; } c[0]=48+l; fprintf(fp,"%s\n+\n%s\n=\n%s\n\n\n\n",a,b,c); fclose(fp); } //------------------------------------ //Add two-digit numbers to at least 2000 does.it is for Multiply function. void big_sum(char a[2002],char b[2002],char c[2002]) { int i,l=0,p; for(i=2000;i>=0;i--) { p=((a[i]-48)+(b[i]-48)+l); c[i]=(p%10)+48; if((p<=9)) { l=0; } else { l=1; } } } //---------------------------------------------------------------------------------------------------- //Multiply two-digit number, 1000 void mul(char a[1002],char b[1002],char cal_name) { FILE *fp; switch(cal_name) { case 'A':fp=fopen("A.txt","a+");break; case 'B':fp=fopen("B.txt","a+");break; case 'C':fp=fopen("C.txt","a+");break; case 'D':fp=fopen("D.txt","a+");break; case 'F':fp=fopen("F.txt","a+");break; } int i,j,q,l=0; char c[2002]; char z[2002]; z[2001]='\0'; c[2001]='\0'; for(i=0;i<=2000;i++) { c[i]='0'; } for(i=1000;i>=0;i--) { //reset z array and l l=0; for(j=0;j<=2000;j++) { z[j]='0'; } for(j=1000;j>=0;j--) { q=(((b[i]-48)*(a[j]-48))+l); z[j-(1000-i)+1000]=(q%10)+48; if(q>9) { l=(q-(q%10))/10; } else { l=0; } if(j==0 && l!=0) { z[999-(1000-i)]=l+48; } } big_sum(c,z,c); } fprintf(fp,"%s\n*\n%s\n=\n%s\n\n\n\n",a,b,c); fclose(fp); } //----------------------------------------------------------------------- void getquestion(char a[1002],char b[1002],int *x) { *x=(rand()%3); getRandomNumber(a); getRandomNumber(b); } //---------------------------------------------------------------- //make 8 questions and do sub,mul and add action and save them in file void Calculate(char cal_name) { //use time_t type and clock() functoin to calculate time FILE *fp; switch(cal_name) { case 'A':fp=fopen("A-time.txt","w+");break; case 'B':fp=fopen("B-time.txt","w+");break; case 'C':fp=fopen("C-time.txt","w+");break; case 'D':fp=fopen("D-time.txt","w+");break; case 'F':fp=fopen("F-time.txt","w+");break; } int i; char s1[1002]; char s2[1002]; time_t start,End,def; int *x; x=(int *)malloc(sizeof(int)); start=clock(); for(i=0;i<8;i++) { getquestion(s1,s2,x); switch(*x) { case 0:add(s1,s2,cal_name);break; case 1:Sub(s1,s2,cal_name);break; case 2:mul(s1,s2,cal_name);break; } } End=clock(); def=End-start; fprintf(fp,"%d mS\n",def); fclose(fp); free(x); } //-------------------------------------------------------- //Empty file from Data may be in file void reset_file(void) { FILE *fp[5]; int i; fp[0]=fopen("A.txt","w"); fp[1]=fopen("B.txt","w"); fp[2]=fopen("C.txt","w"); fp[3]=fopen("D.txt","w"); fp[4]=fopen("F.txt","w"); for(i=0;i<5;i++) { fclose(fp[i]); } } //----------------------------------------- //save calculator time in Arranged form in File and show it in standard output void save_report(void) { FILE *fp[6]; int time[5]; char cal_name[5]={'A','B','C','D','F'}; char Temp; int i,j,temp; fp[0]=fopen("A-time.txt","r"); fp[1]=fopen("B-time.txt","r"); fp[2]=fopen("C-time.txt","r"); fp[3]=fopen("D-time.txt","r"); fp[4]=fopen("F-time.txt","r"); fp[5]=fopen("sort calculator.txt","w"); for(i=0;i<5;i++) { fscanf(fp[i],"%d",&time[i]); fclose(fp[i]); } for(i=0;i<5;i++) { for(j=0;j<5;j++) { if(time[i]>time[j]) { temp=time[j]; time[j]=time[i]; time[i]=temp; Temp=cal_name[j]; cal_name[j]=cal_name[i]; cal_name[i]=Temp; } } } for(i=4;i>=0;i--) { fprintf(fp[5],"%d. %c %d mS\n",5-i,cal_name[i],time[i]); printf("%d. %c %d mS\n",5-i,cal_name[i],time[i]); } fclose(fp[5]); } //---------------------------------------------------- int main() { srand(time(NULL)); reset_file(); Calculate('A'); Calculate('B'); Calculate('C'); Calculate('D'); Calculate('F'); save_report(); return 0; } |
این فقط برای هزار رقمی ها کار می کنه
عالی بود
سلام برنامه جالبی بود با اجازتون من برای پروژه درس دانشگاه از تابع compareتون استفاده می کنم
تشکر ، این کد ها رو گذاشتم که همه استفاده کنیم
سلام
متشکرم بابت برنامه.
توی DEV c++ اجرا نمیشه ؟
توی code::blocks یا ویژوال استادیو تست کنید.
برای اجرا در dev باید یک دو تا چیز کم کنید و یا اضافه کنید.
slm mishe adrse emailtono bedid
سلام ایمیلت رو خوندم – متاسفانه خیلی درگیره کارام هستم وقت نمی کنم پست رو آپدیت کنم ولی از این کد می تونی برای کار با اعداد بزرگ استفاده کنی:
https://github.com/t3nsor/codebook/blob/master/bignum.cpp
کدش بسیار با کیفیت و استاندارد است.
سلام.ببخشید کد تفریق شما فقط در حالتی که دو عدد با تعداد ارقام برابر و هرکدام فقط ۵۰ رقم باشند جواب میده.اگه ما دو تا string داشته باشیم که عدد ها هم معلوم نیست که تعداد ارقامشون برابر باشه یا نه اونوقت چطوری میشه؟
ممنون
سوالی که من اینجا حل کردم مربوط به اعداد هزار رقمی .ولی شما فکر کن یک عدد داری دویست رقم است اون موقع شما می تونی هشتصد تا صفر پشتش بذاری و بفرستی به تابع.