PDA

View Full Version : سوال: Huge Integer با آرایه ها



MP.C-Writer
یک شنبه 12 تیر 1390, 16:09 عصر
سلام به همگی. این که می گم یه پروژه است توی ++C .
میگه کلاس HugeInteger را طوری پیاده سازی کنید که با یک آرایه یک عدد صحیح 40 رقمی را ذخیره کند. سپس توابع عددی جمع، تفریق، ضرب و تقسیم را برای دو شیء از این کلاس پیاده سازی کنید. :افسرده:

خیلی گیر کردم. مخصوصا توی تقسیمش. اگر کمک کنید ممنون می شم.:گریه:

یوسف زالی
دوشنبه 13 تیر 1390, 21:20 عصر
شما برای تقسیم یکی یکی از مقسوم کم کنید.
مثلا 26 تقسیم بر 7 میشه:
19 = 7 - 26
12 = 7 - 19
5 = 7 - 12

سه بار کم شد. پس میشه 3 با باقی مانده 5.
همون چیزیه که دوم ابتدایی خوندیم!

MP.C-Writer
سه شنبه 14 تیر 1390, 09:41 صبح
خیلی خیلی ممنون.:بوس:

ولی برای ضرب و جمع و تفریق هم وقتی کد می نویسم، دچار مشکل می شه و اعداد اشتباهی چاپ می کنه، درحالی که کد رو 10 - 20 بار خوندم و چک کردم. هیچ مشکلی نداره.

یوسف زالی
سه شنبه 14 تیر 1390, 10:02 صبح
کدتون رو بگذارید تا ببینم.
تشکر هم دکمه داره رااااحت!!!

quiet_programmer
سه شنبه 14 تیر 1390, 10:46 صبح
با سلام.

اول آرایه رو با صفر مقدار دهی اولیه کنیند. یعنی تمامی خانه های آرایه عدد اول و عدد دوم رو با صفر مقدار دهی کنید.
برای دریافت عدد و ذخیره در آرایه از کد زیر استفاده کنید: (N تعداد رقمهای عدد)

void GetFisrtNumber()
{
cout<<"Please Enter First Number:";
Index1=0;
while((Index1<DigitLen)&&((ch=getche())!=N))
Number1[Index1++]=ch-48;
cout<<endl;
}

برای دریافت عدد دوم هم مثل کد بالا عمل کنید:

void GetSecondNumber()
{
cout<<"Please Enter Second Number:";
Index2=0;
while((Index2<DigitLen)&&((ch=getche())!=N))
Number2[Index2++]=ch-48;
cout<<endl;
}

با توجه به کد همونطور که معلومه عدد با ارزش بیشتر تو ایندکس صفر از آرایه قرار میگیره. پس برای جمع کردن این دو عدد باید از آخرین ایندکسی که عددی داخلش ذخیره شده شروع به جمع کردن کرد تا به ایندکس صفر برسین.

توضیح: توی این کد:
Index1: این متغییر تعداد ارقام وارد شده به آرایه اول رو نشون میده
Index2: این متغیر تعداد ارقام وارد شده در به آریاه دوم رو نشون میده
برای جمع کردن هم شما یه متغیر اضافه برای نگهداری Carry خواهید داشت.

پس برای جمع اول ایندکس Index1 از آرایه اول با ایندکس Index2 از آرایه دوم و مقدار Carry جمع میشه و بعد ایندکس Index1-1 از آرایه اول با ایندکس Index2-1 از آرایه دوم و Carry جمع میشه و الی آخر. تا یکی از ایندکس Index1 یا Index2 به صفر برسه. در همین حال با جمع هر عدد مقدار Carry رو هم بروزرسانی میکنیم. مقدار اولیه Carry صفره. بعد از جمع دو رقم حاصل رو بر 10 تقسیم میکنیم و خارج قسمت رو در Carry و باقی مانده رو به عنوان حاصل در آرایه نتیجه نگهداری میکنیم. در نهایت اگر آرایه اول به صفر نرسیده باشه(یعنی آرایه دوم زودتر به ایندکس صفر رسیده و باعث شده تا دیگه عمل جمع صورت نگیره) اونوقت ارقام باقی مونده از آرایه اول رو با Carry جمع میکنیم و در آرایه نتیجه نگهداریشون میکنم. برای آرایه دوم هم همین شرایط صدق میکنه. فقط باید حواستون باشه که بعد از جمع باید مثل جمعهای دیگه مقدار Carry رو مقدار دهی کنید.

در نهایت آخرین عددی که تو آرایه نتیجه قرار گرفته رو با مقدار Carry جمع میکنید.

کد جمع دو آرایه رو اینجا گزاشتم:

void Sum()
{
int Carry=0;
int i;
int Tindex1=Index1,Tindex2=Index2;
for(i=0;(Index1>0)&&(Index2>0);i++)
{
Result[i]=(Number1[Index1-1]+Number2[Index2-1]+Carry)%10;
Carry=(Number1[--Index1]+Number2[--Index2]+Carry)/10;
}

for(;Index1>0;)
{
Result[i++]=(Number1[Index1-1]+Carry)%10;
Carry=(Number1[--Index1]+Carry)/10;
}

for(;Index2>0;)
{
Result[i++]=(Number2[Index2-1]+Carry)%10;
Carry=(Number2[--Index2]+Carry)/10;
}

Result[i]+=Carry;

Index1=Tindex1;
Index2=Tindex2;
}

برای چاپ نتیجه هم از ایندکس آخر شروع میکنید تا زمانی که اون ایندکس از آرایه مقدار صفر داشت رو بیخیال میشین و فقط از ایندکس یکی کم میکنید تا به اولین رقمی برسین که مقدار نابرابر با صفر داره بعد این کار از ایندکسی که عددی غیر از صفر داره به بعد رو تو خروجی نمایش بدین.

for(index=DigitLen;Result[index]==0 && index>=0;index--);
for(;index>=0;index--)
cout<<Result[index];
cout<<endl;

برای تفریق هم شما از عدد دوم مکمل 10 میگیرین و بعد دو عدد رو با هم جمع میکنید. در نهایت اگه مقدار Carry برایر صفر شد عدد حاصل منفیه وگرنه عدد مثبته. در صورتی که عدد منفی باشه قبل چاپ باید از نتیجه هم مکمل 10 بگیرین و بعد چاپ کنین. برای مکمل 10 به این شکل عمل میکنید که از رقم یکان شروع میکنید و تا زمانی که به یه عدد غیر صفر نرسیدین جلو میرین به محض رسیدن به رقم غیر صفر 10 رو از اون رقم کم میکنید. بعد 9 رو از بقیه آرقام کیم میکنید.

void Compelements10OfNumber2()
{
int i;
for(i=Index2-1;Number2[i]==0 && i>=0;i++);
Number2[i--]=10-Number2[i];
for(;i>=0;i--)
Number2[i]=9-Number2[i];
}

دیگه حوصلم سر رفت فقط کد میزارم:
تفریق:

void Min()
{
Compelements10OfNumber2();

int Carry=0;
int i;
for(i=0;(Index1>0)&&(Index2>0);i++)
{
Result[i]=(Number1[Index1-1]+Number2[Index2-1]+Carry)%10;
Carry=(Number1[--Index1]+Number2[--Index2]+Carry)/10;
}

for(;Index1>0;)
{
Result[i++]=(Number1[Index1-1]+Carry+9)%10;
Carry=(Number1[--Index1]+Carry+9)/10;
}

for(;Index2>0;)
{
Result[i++]=(Number2[Index2-1]+Carry+9)%10;
Carry=(Number2[--Index2]+Carry+9)/10;
}

if(Carry!=0)
Result[i]=0;
else
Negative=True;
}

مکمل 10 از حاصل:

file:///C:/Users/PARSEC%7E1/AppData/Local/Temp/moz-screenshot.pngvoid Complements10OfResult()
{
int i;
for(i=0;Result[i]==0 && i<=DigitLen;i++);
Result[i++]=10-Result[i];
for(;i<=DigitLen;i++)
Result[i]=9-Result[i];
}

برای چاپ هم:

if(Negative)
Complements10OfResult();
if(Negative)
cout<<"-";
if(Negative)
for(index=DigitLen;Result[index]==9 && index>=0;index--);
else
for(index=DigitLen;Result[index]==0 && index>=0;index--);
for(;index>=0;index--)
cout<<Result[index];
cout<<endl;