Tam Sürümünü Görmek İçin : Büyük Sayılarda Faktöriyel Alma (C++)
Arkadaşlar, ben bir faktöriyel alma fonksiyonu hazırladım, fakat 12'den büyük sayılarda gerçek sonucu vermiyor. Bu yüzden de makul bir sayıya kadar switch-case mi kullanmalıyım bu fonksiyonu tamamlayabilmek için, yoksa büyük sayıları da doğru hesaplayabilen bir yöntem var mı?
Kullandığım kod:
int fakt(int x)
{
int i=1;
int s=1;
if(x<1)
{
return 0;
}
else if(x<12)
{
for(i=1;i<=x;i++) s*=i;
return s;
}
else
{
switch(x)
{
case 12: return 479001600; break;
case 13: return 6227020800; break;
case 14: return 87178291200; break;
case 15: return 1307674368000; break;
case 16; ...........
default:
return 0;
}
}
}
Edit:
Derlerken farkettim; switch sonuçları için de long tipi için çok uzun diyor...
Değişkenleri double türünden yaparsın sonuçlar doğru olur kanımca.
BFS, dediğin gibi double haline getirdim yine yanlış sonuç verdi, zaten switch'leri de double yaptığımda aşağıdaki gibi oluyor;
double fakt(int x)
{
double i=1;
double s=1;
if(x<1)
{
return 0;
}
else if(x<12)
{
for(i=1;i<=x;i++) s*=i;
return s;
}
else
{
switch(x)
{
case 12: s=479001600; break;
case 13: s=6227020800; break; //64. satır
case 14: s=87178291200; break; //65. satır
case 15: s=1307674368000; break; //66. satır
default: return 0;
}
return s;
}
}Ama yine de derlediğimde;
matematik.h:64: error: integer constant is too large for ‘long’ type
matematik.h:65: error: integer constant is too large for ‘long’ type
matematik.h:66: error: integer constant is too large for ‘long’ type
diyor... Sanırım fonksiyonun çıktısını doğrudan int olarak varsayıyor, double olarak tanımlamama rağmen too large for ‘long’ type diyor...
acehreli
27/04/2008, 18:49
utdemir, yazdigin sabitlerin bir long turune sigmadigini sen de goruyorsun degil mi? O sabitleri de double yazabilmek icin sonlarina ".0" koyabilirsin:
case 13: s=6227020800.0; break;
Ama double'in da cozum olmadigini goreceksin; sayilar cabucak cok buyuyecekler. Onun icin kendin bir "buyuk sayi" kullanmak isteyebilirsin. Buna daha once deginmistik:
http://forum.ceviz.net/c-faktoriyel-hesaplamasi-soru-t52500.html?t=52500
Ali
Barcoder
28/04/2008, 17:06
Kendine ait çok büyük sayılar üzerine işlem yapabilen bir sınıf geliştirmelisin.Yüzlerce ,binlerce basamağı tutabilirsin, ama bu ileri düzey bilgi gerektirir. Bence büyük sayıları bir kenara bırakıp daha farklı ve seni adım adım geliştirecek örneklere göz atabilirsin. Tabii foruma devamlı girebiliyor olsam (keşke :)) yardımcı olabilirdim..
sekizbit
29/04/2008, 03:59
Double 8 byte`lik bir degiskendir ama bunun bildigim kadari ile isaretli sayilarda sadece 10 bit`i isaretsiz sayilarda 11 bit`i sayinin tam sayi kismi icin kullanilabilir. Geri kalan kisim virgulden sonrasini icin ayrilmistir.
Kendi denemelerimle buldugum kadari ile C++`ta ekstra bi class yazmadan tutturabileceginiz max. sayi "long long unsigned int" turunden degiskende tutulur ve oda 2^64 -1 (2 uzeri 64 eksi 1)dir.
daha once ufak bi isim icin yazdigim bir class vardi istersen onu kullanabilirsin.
Cok performansli bir kod degil belki birilerinin isine yarar, yukarda h olarak define edilmis alana kac basamakli bir sayi yazmak istiyorsaniz onun 9 da birini yazmaniz gerekli. yani 9 bin basamakli bir sayi icin oraya 1000 yazmaniz gerekiyor.
String veya daha buyuk sayisal degiskenler kullanilarak daha performansli hale getirilebilir ama simdilik birilerinin isini gorebilir.
Kolay gelsin.
#define h 1000 //basamak sayisinin 9 da biri
#define max 100000000 //integer boyutu
using namespace std;
//her int de 9 hane var.
class c_sayi
{
public :
int* sayi;
c_sayi();
friend c_sayi operator+(const c_sayi& left, const c_sayi& right);
friend c_sayi operator+(const c_sayi& left, int);
friend c_sayi operator*(const c_sayi& left, int a);
void print();
};
void c_sayi::print()
{
int i;
for(i=0;i<h;i++)
{
printf("%.9d", sayi[i]);
}
printf("\n");
}
c_sayi operator*(const c_sayi& left, int a)
{
int i;
c_sayi tmp = left;
for(i=1;i<a;i++)
tmp = tmp + left;
return tmp;
}
c_sayi operator+(const c_sayi& left, const c_sayi& right)
{
int i;
c_sayi tmp;
unsigned long long int sonuc ;
unsigned long long int yeni;
unsigned int elde=0;
for(i=h-1;i>=0 ; i--)
{
sonuc = left.sayi[i] + right.sayi[i] + elde;
yeni = sonuc - (sonuc%(max*10));
elde = yeni/(max*10);
tmp.sayi[i] = sonuc%(max*10); ;
}
if(elde>0)
cout<<"owerflow\n";
return tmp;
}
c_sayi operator+(const c_sayi& left,int a)
{
int i;
c_sayi tmp;
unsigned long long int sonuc ;
unsigned long long int yeni;
unsigned int elde=0;
for(i=h-1;i>=0 ; i--)
{
sonuc = left.sayi[i] + a + elde;
yeni = sonuc - (sonuc%(max*10));
elde = yeni/(max*10);
tmp.sayi[i] = sonuc%(max*10); ;
if(elde==0)
break;
}
if(elde>0)
cout<<"owerflow\n";
return tmp;
}
c_sayi::c_sayi()
{
sayi = new int[h];
int i;
for(i=0;i<h;i++)
sayi[i]=000000000 ;
}
Ekleme, class`in deconstructor`u bulunmadigi icin hafizada birakilmayan yerler olusmasina yol acabilir :)
Bu kadar derin bir işin içine girdiğimi bilmiyordum ben ya.. :D long long unsigned int deneyeceğim şimdilik, c++ bilgim toplama çıkarma yapmaya yarıyor şimdilik sadece... İstediğim de sadece ufak bir faktöriyel fonksiyonunda 12'den yüksekleri hesaplayabilmekti... Teşekkürler arkadaşlar verdiğiniz bilgiler için...
Sekizbit verdiğin kodu da keydettim, işime yarar ileride...
İyi çalışmalar.
m_c_mehmet
22/05/2008, 11:17
fonksiyonlu program yazmadım çünkü şu an pek bilgi sahibi değilim
o yüzden basit bi program gönderdim umarım işine yarar.
#include <stdio.h>
void main ()
{
int fak=1, i, x;
printf("bir sayi giriniz:");
scanf("%d" , &x);
for(i=1;i<x+1;i++)
fak=fak*i;
printf("sayinin faktoriyeli=%d\n" , fak);
}
acehreli
22/05/2008, 17:01
m_c_mehmet, soruyu anlamadin galiba. Senin programin da belli bir sayidan sonra dogru sonuc vermiyor. :( Sonucu bir 'int' degiskende tutuyorsun. Eger calistigin ortam 32 bitlikse, 'int'te yaklasik olarak 4 milyardan daha buyuk bir deger tutamazsin. 13!'in sonucu 6 milyardan buyuk bir sayidir:
http://www.exept.de:8080/stt/factorials.stt
Buradaki sorun da o iste...
Ali
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.