View Full Version : سوال: چگونگی محاسبه یک عدد بزرگ و نمایش آن
OMIDAMtak
دوشنبه 24 آذر 1393, 22:42 عصر
سلام دوستان.
از دوستان عزیز خواهش میکنم منو در این زمینه راهنمایی کنند:
در محیط جاوا اگر بخوایم یک برنامه بنویسیم که فاکتوریل یک عدد بزرگ مثلا 800 یا 2000 رو نمایش بده باید از چه متغیری کمک بگیریم؟
من کلی تحقیق کردم و به این نتایج رسیدم:
1.متغیری وجود نداره که بتونه این مقدار رو در داخل خودش قرار بده!
2.فاکتوریل عدد هزار یک عدد 2567 رقمی میشه!
3.باید از رشته استفاده کنیم!
اگر کسی میدونه چطوری باید این برنامه رو حل کرد لطف کنه و راهنمایی کنه،خواهشا اگر راهنمایی میکنید کامل و واضع باشه
اگر شد نحوه استفاده از استرینگ در جاوا برای این چنین برنامه های رو توضیح بدین...یک دنیا ممنون از همتون...
محمد فدوی
سه شنبه 25 آذر 1393, 01:52 صبح
سلام.
از کلاس java.math.BigInteger استفاده کن.
نمونه توی اینترنت زیاد هست. موفق باشی.
OMIDAMtak
سه شنبه 25 آذر 1393, 10:23 صبح
سلام.
از کلاس java.math.BigInteger استفاده کن.
نمونه توی اینترنت زیاد هست. موفق باشی.
سلام میتونی بیشتر توضیح بدید...من جاوا زیاد بلد نیستم نمیدونم چطور باید اینی که میگید کد نویسی کنم.
ahmad.mo74
سه شنبه 25 آذر 1393, 11:36 صبح
http://stackoverflow.com/a/8992471/3767784
OMIDAMtak
سه شنبه 25 آذر 1393, 17:08 عصر
http://stackoverflow.com/a/8992471/3767784
سلام.
من نک تک اون کدها رو در برنامه جی بیلدر اجرا گرفتم خیلی ارور میداد بیشتر ارور ها این بود که بی اینتیجر رو نمیفهمه،لطفا خواهشا این کد رو برای من توضیح بدین...
ممنونم...
محمد فدوی
سه شنبه 25 آذر 1393, 18:03 عصر
من یه مثال نوشتم برات اینجا. تابع فاکتوریل رو هم برای اعداد long و هم برای BigIntegerها پیاده سازی کردم. شاید کمکت کنه:
import java.math.BigInteger;
public class Factorial {
private static long fact(long n) {
return n > 1 ? n * fact(n - 1) : 1;
}
private static BigInteger fact(BigInteger n) {
return n.compareTo(BigInteger.ONE) == 1 ? n.multiply(fact(n.subtract(BigInteger.ONE))) : BigInteger.ONE;
}
public static void main(String[] args) {
long n1 = 10L;
System.out.printf("%d! = %d\n", n1, fact(n1));
BigInteger n2 = new BigInteger("1234");
System.out.printf("%s! = %s\n", n2, fact(n2));
}
}
البته با این تابع نمیتونی بازم فاکتوریل یه عدد ۲۵۶۷ رقمی رو محاسبه کنی! و اگه چنین قصدی داری فکر نکنم به این سادگیا حل شه مشکلت!
OMIDAMtak
سه شنبه 25 آذر 1393, 18:30 عصر
من یه مثال نوشتم برات اینجا. تابع فاکتوریل رو هم برای اعداد long و هم برای BigIntegerها پیاده سازی کردم. شاید کمکت کنه:
import java.math.BigInteger;
public class Factorial {
private static long fact(long n) {
return n > 1 ? n * fact(n - 1) : 1;
}
private static BigInteger fact(BigInteger n) {
return n.compareTo(BigInteger.ONE) == 1 ? n.multiply(fact(n.subtract(BigInteger.ONE))) : BigInteger.ONE;
}
public static void main(String[] args) {
long n1 = 10L;
System.out.printf("%d! = %d\n", n1, fact(n1));
BigInteger n2 = new BigInteger("1234");
System.out.printf("%s! = %s\n", n2, fact(n2));
}
}
البته با این تابع نمیتونی بازم فاکتوریل یه عدد ۲۵۶۷ رقمی رو محاسبه کنی! و اگه چنین قصدی داری فکر نکنم به این سادگیا حل شه مشکلت!
سلام.مرسی از اینکه وقت با ارزشتو صرف کد نویسی برای من کردی واقعا خدا خیرت بده ولی من دقیقا یه برنامه ای میخوام که بتونه فاکتوریل یک عدد بزرگ مثلا 1000 یا 2000 رو محاسبه کنه
من یک کد پیدا کردم که تو این کد با استفاده از کتابخانه مخصوص اعداد بسیار بزرگ تونسته این مشگل رو حل کنه ولی من بلد نیستم چطوری این برنامه رو تغییر بدم که به جای مثلا تفریق یا جمع اعداد بتونه فاکتوریل رو محاسبه کنه
این کد برنامه است
import java.math.BigDecimal;
public class Untitled1 {
public static void main(String []args){
BigDecimal bd1 = new BigDecimal("10000000123000000006465465565465465464546464465464");
BigDecimal bd2 = new BigDecimal("546546464546000123000000006545646545");
System.out.println("bd1*bd2 ="+ bd1.multiply(bd2));
}
}
این کد تو نمایش نتیجه محدودیت نداره،مثلا من یک عدد بسیار بزرگ رو به توان یک عدد بسیار بزرگ دیگه رسوندم،نتیجه حاصل شد یک عدد حدود 861000 رقمی! این برنامه هیچ محدودیتی نداره فقط بلد نیستم جطوری با استفاده از این متغیر بیگ دسیمال فاکتوریل رو محاسبه کنم...تو رو خدا کمک کنید...
ahmad.mo74
سه شنبه 25 آذر 1393, 19:04 عصر
سلام، این که کار میکنه، نمیدونم مشکلتون چیه!
public class Factorial {
public static void main(String[] args) {
System.out.println(factorial(2000));
}
static BigInteger factorial(int n) {
if (n == 0) {
return BigInteger.ONE;
}
BigInteger b = BigInteger.ONE;
for (int i = n; i > 1; i--) {
b = b.multiply(BigInteger.valueOf(i));
}
return b;
}
}
خروجی :
33162750924506332411753933805763240382811172081057 80394571935437060380779056008224002732308597325922 55402352941225834109258084817415293796131386633526 34368890563405855616394060511725257187064785639354 40454052439574670376741087229704346841583437524315 80877533645127487995436859247408032408946561507233 25065279765575717967153671868935905611281587160171 72326571561100042140124204338425737127001758835477 96899921283528996665853405579854903657366350133386 55040117201215263548803826815215224692099520603156 44185654806759464970515522882052348999957264508140 65536678969532101467622671332026831552205194494461 61823927520402652972263150257475204829606475092739 41658562835317795744828763145964503739913273341772 63608852490093506621610144459709412707821313732563 83157230201994991495831647094277447387032798554967 42986088393763268241524788343874695958292577405745 39837501585815468136294217949972399813599481016556 56387603422731291225038470987290962662246197107660 59315502018951355831653578714922909167790497022470 94611937607785165110684432255905648736266530377384 65039078804952460071254940261456607225413630275491 36715834060978310749452822174907813477096932415561 11339828051358600690594619965257310741177081519922 56451677857145805660218565476095237746301667942248 84444857983498015480326208298909658573817518886193 76692828279888453584639896594213952984465291092009 10371004614944991582858805076186792494638518087987 45128914080193400746259200570987295785996436506558 95612410231018690556060308783629110505601245908998 38341079936790205207685866918347790655854470014869 26569246319333376124280974200671728463619392496986 28468719993450393889367270487127172734561700354867 47750910295552395354794110742191330135681954109194 14627664175421615876252628580898012224438902486771 82054959415751991701271767571787495861619665931878 85514183578209260148207177733173539603430496908207 05899587013819808130355901607629083885745612882176 98136182483576739218303118414719133986892842344000 77924669120976673165143349443747323563657204884447 83318549416930301245316762327453678793228474738244 85092283139952509732505979127031047683601481191102 22925337269769382367005756561240029057604385285290 29376064795334581796661238396052625491071866638693 54766108455046198102084050635827676526589492393249 51968595417167241932953068367349554400458635983816 10430594498266275306054235807558941082788804278259 51089880635410567917950974017780688782869810219010 90014835206168888372025031066592206860148364983053 27820882635365580436056867812841692171330471411763 12175895777122637584753123517230990549829210134687 30420589801441806387538266416989770423775940628087 72537022654265305808623793014226758211871435029186 37636340300173251818262076039747369595202642632364 14544685111342720215045838385101013694131303485622 19166316238926327658153550112763078250599691588245 33457435437863683173730673296589355199694458236873 50883027865770087974988999234355556624068283476378 46851838449736488739524751032242221105612012958296 57191368108693825475764118886879346725191246192151 14473883626959164367249007165342822815266124780046 39225449451703637236279407577845420910483054616561 90622174286981602973324046520201992813854882681951 00728286970107073750092766648750217477537274235150 87482467202741700315811228058961781221607474379475 10950620938556674581252518376682157712807861499255 87613235295042234638787895485088576446613629039412 76659780442020922813379871159008962648789424132104 54925003566670632909441579372986743421470507213588 93201958072306478149842952259558901275482397177332 57229103257609297907332995450563883626404746502450 80809469116072632087494143973000704111418595530278 82735765481918200244969776111134631819528276159096 41897909581173386272060889104329452449785351470141 12442143055486089639578378347325323595763291438925 28839398625627324286277556314046383038916842163311 34456363095719659784663385514923161963356753551384 03425804162919837822266909521770153175338730284610 84188655413832917195133211789572854166208482368281 79325129312375215419269702697032994776438233864830 08871530373405666383868294088487730721762268849023 08493466119426018027261380210800507821574100605484 82013478595781027707077806555127725405016743323960 66253216415004808772403047611929032210154385353138 68553848642557079079534117651957118868373988068389 57927437496834981429232921963097770901439368436553 33359307820181312993455024206044563340578606962471 96150560339489952332180043435996725662392719643540 28720554750120798543319706747973131268135236537440 85662263206768837585132782896252333284341812977624 69707954343600349234315923967476363891211528540665 77836462139112474470512552263427012395270181270454 91648045932248108858674600952306793175967755581011 67994000524980630376314134441226903703498735579991 60092592480750524855415682662817608154463083054066 77412630124441864204108373119093130001154470560277 77372437806718889977085105672727678124719883285769 58442175888951604678682048100100478164623582208385 32488134270834079868486632162720208823308727819085 37884546913155602172887312190739396520926022910147 75270809308653649798585540105774502792898146036884 31821508637246216967872282169347370599286277112447 69092090298832016683017027342025976567170986331121 63495021712644268271196502640542282317596308744753 01847194095524263411498469508073390080000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 000000000000000000000000000000000000
در ضمن بهتره از recursion استفاده نکنید چون ممکنه stackoverflow اتفاق بیفته!
محمد فدوی
سه شنبه 25 آذر 1393, 19:18 عصر
در ضمن بهتره از recursion استفاده نکنید چون ممکنه stackoverflow اتفاق بیفته!
ممنون، این حرف درسته. نباید بصورت بازگشتی نوشته بشه. این بهتره:
private static BigInteger fact(BigInteger n) {
BigInteger result = BigInteger.ONE;
for(BigInteger i = BigInteger.valueOf(2); i.compareTo(n) <= 0; i = i.add(BigInteger.ONE)) {
result = result.multiply(i);
}
return result;
}
با این من راحت فاکتوریل ۱۰۰۰۰۰ رو محاسبه کردم.
ahmad.mo74
سه شنبه 25 آذر 1393, 21:53 عصر
این برنامه رو multi thread اش کردم چون دیدم برای اعداد بزرگ خییییلی زمان میبره محاسبش، ولی الان تست کردم فاکتوریل 1000000 رو تو 31 ثانیه حساب کرد (قبلا بالای 2 3 دقیقه طول میکشید !!)
public class Factorial {
public static void main(String[] args) {
long l = System.currentTimeMillis();
System.out.println(new Factorial().calculate(1000000, 10000));
System.out.println("Execution time : " + (System.currentTimeMillis() - l) + " ms");
}
public BigInteger calculate(long n, int chunks) {
assert n >= 0;
if (n == 0) {
return BigInteger.ONE;
}
long len = n % chunks == 0 ? n / chunks : n / chunks + 1;
long from = 1, to = 0;
List<ContinuousSequence> sequences = new ArrayList<>();
while (to != n) {
to = Math.min(to + len, n);
sequences.add(new ContinuousSequence(from, to));
from = to + 1;
}
final List<BigInteger> results = Collections.synchronizedList(new ArrayList<>());
sequences.parallelStream().map(ContinuousSequence: :calculate).forEach(results::add);
return calculate(results);
}
private BigInteger calculate(List<BigInteger> sequence) {
int size = sequence.size();
if (sequence.size() <= 10) {
return new DiscreteSequence(sequence).calculate();
}
List<DiscreteSequence> sequences = new ArrayList<>();
int n = 0;
while (n != size) {
sequences.add(new DiscreteSequence(sequence.subList(n, n = Math.min(n + 10, size))));
}
final List<BigInteger> results = Collections.synchronizedList(new ArrayList<>());
sequences.parallelStream().map(DiscreteSequence::c alculate).forEach(results::add);
return calculate(results);
}
private static class ContinuousSequence {
private final long from;
private final long to;
private ContinuousSequence(long from, long to) {
assert to >= from;
this.from = from;
this.to = to;
}
private BigInteger calculate() {
long n = to - from;
BigInteger result = BigInteger.valueOf(from);
long temp = from;
while (n != 0) {
result = result.multiply(BigInteger.valueOf(++temp));
n--;
}
return result;
}
}
private class DiscreteSequence {
private final List<BigInteger> elements;
private DiscreteSequence(List<BigInteger> elements) {
this.elements = elements;
}
private BigInteger calculate() {
BigInteger result = BigInteger.ONE;
for (BigInteger element : elements) {
result = result.multiply(element);
}
return result;
}
}
}
خروجی :
58079294693243298369807363635943203041896525806478 4233...
Execution time : 31049 ms
عددش خیلی بزرگ بود بخشیشو گذاشتم :)
OMIDAMtak
سه شنبه 25 آذر 1393, 22:05 عصر
آقا من اید کد ها رو که تو جی بیلدر میزنم قبل از اجرا کلی ارور تو پوشه اجرا میاد...کلی ارور داره...چی کار کنم؟؟؟
دستتون درد نکنه خیلی زحمت کشیدین....
ahmad.mo74
سه شنبه 25 آذر 1393, 22:15 عصر
من تا حالا با jbuilder کار نکردم ولی احتمالا jdk رو مشخص نکردید، چیز دیگه ای به ذهنم نمیرسه!
OMIDAMtak
سه شنبه 25 آذر 1393, 22:21 عصر
این jdk رو چطوری مشخص کنم...من برنامه نویسی بلد نیستم زیاد....
محمد فدوی
سه شنبه 25 آذر 1393, 22:59 عصر
اولا دقت کن که اسم فایلی که کلاسی که احمدجان اینجا گذاشتن رو توی مینویسی حتما Factorial.java باشه (یعنی هم اسم کلاس)
ثانیا دقت که توی JBuilder توی هیچ فولدر زیریای قرار نداشته باشه و مستقیما توی فولدر اصلی پروژه قرار داشته باشه.
خطاهایی که میده رو یه نگاه اجمالی بنداز ببین اگه چیزی مبنی بر اینکه JDK رو پیدا نکرده توش میبینی سعی کن اصلاحش کنی.
اگه همه اینکارا رو کردی و بازم خطاها رو نتونستی از بین ببری اینجا بذارشون شاید بتونیم کمک کنیم.
پ.ن: JBuilder یه محیط نسبتا خوبه... ولی بهتره از IDEهای روپا تری مثل Netbeans یا Eclipse یا IntelliJ IDEA استفاده کنی.
OMIDAMtak
سه شنبه 25 آذر 1393, 23:16 عصر
اقا همه این کارها رو اناجم دادم نشد...
اقا اصلا نمیشه با استفاده از آرایه این سوال رو حل کرد تو حالت معمولی ما اینجوری فاکتوریل میگیریم:
package untitled1;
public class Factorial {
public static void main(String[] args) {
int f,i,n=4;
f=1;
for(i=1;i<=n;i++)
f*=i;
System.out.print("f is:"+f);
}
}
این کد تو برنامه جی بیلدر من بدون هیچ مشکلی جواب میده و نتیجه 24 رو در پایین چاپ میکنه...
حالا به چطوری میشه این نتیجه رو انداخت تو یک آرایه و بعد آرایه رو چاپ کرد؟؟؟
چون همون طور که گفتید متغییری به این ظرفیت وجود نداره...
اگر بخوایم با رشته این کارو انجام بدین چی کار میکنم؟؟؟
محمد فدوی
چهارشنبه 26 آذر 1393, 01:11 صبح
شما برای اینکار باید چرخ رو از اول اختراع کنید! در صورتی که BigInteger خودش اینکار رو کرده و هر عدد رو بصورت یه آرایهی پویا از بایتها میبینه...
کافیه از کلاس java.util.BigInteger توی این کدتون استفاده کنید...
OMIDAMtak
چهارشنبه 26 آذر 1393, 10:21 صبح
سلام.بچه ها چطوری میشه نتیجه یک محاسبه رو داخل یک رشته ریخت؟؟؟
مثلا در این کد به جای اینکه حاصل محاسبه داخل متغییر f ریخته بشه در داخل یک رشته یا string ریخته بشه!
package untitled1;
public class Factorial {
public static void main(String[] args) {
int f,i,n=4;
f=1;
for(i=1;i<=n;i++)
f*=i;
System.out.print("f is:"+f);
}
}
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.