Herkese merhaba aslında sorum sadece C dili ile alakalı bir durum değil daha çok genel bir soru. Ancak sıkıntıyı C dilinde yaşadığım için konuyu C ana başlığında açıyorum.
Her dil python gibi integer işlemleri için bir sınırlama koymamazlık yapmıyor. Biz python yazarken sayıların ram’de kapladığı alan ve bu sayının alacağı en büyük değeri ile uğraşmak zorunda kalmıyoruz.
sayi = 1324235784395643785638423423423523334
yazıyoruz ve sayi değişkeni o sayı oluyor
C ve bazı diğer dillerde ise bu çok büyük sayılar için, int, short, long gibi sayı bazlı verileri tutmaya yarayan veri türleri var. Bazı özel durumlarda long int bile yetersiz kalıyor. C de bu tür büyük sayıları tutmak ve manipüle etmek için veri tipi oluşturmaktan başka daha pratik ve geçerli bir yol var mı? Diğer dillerde bu işlemler nasıl yapılıyor?
Struct ile bir veri türü tanımlayıp onun içinde parçalar halinde tutmayı düşündüm ancak bu sayının kendisini kullanmak isteyip bu parçaları birleştirmeye çalışınca da sıkıntı yaşıyorum.
Açıkçası cevabı bilmiyorum. Aklıma sayıyı bir dizinin ilk elemaninda tutup sayı belli bir basamağa ulaştıktan sonra geriye kalan kısmını dizinin ikinci elemaninda tutmak ve sayı büyüdükçe dizinin eleman sayısını arttırmak geldi. Çözümü varsa ben de merak ettim açıkçası guzel bir soru, teşekkürler.
Aşağıdaki bağlantıları bir inceleyin isterseniz.
https://gmplib.org/
https://www.cs.colorado.edu/~srirams/courses/csci2824-spr14/gmpTutorial.html
gmplib’i Linux’e aşağıda gösterildiği gibi yükleyebilirsiniz.
sudo apt-get install libgmp3-dev
Gmp ile ilgili bir örnek:
test.c
#include <gmp.h>
int main(){
// değişkenleri deklare edelim.
mpz_t str1;
mpf_t int1;
// int1'i ilklendirelim.
mpf_init(int1);
/*
str1'i ilklendirip ayarlayalım.
Kulanım Şekli:
mpz_init_set_str(degisken_ismi, string_verisi, sayı_tabanı)
*/
mpz_init_set_str(str1, "1000000000000000000000000000000000000000000000000000000000", 10);
// str1 değişkenini int1 değişkenine atayalım.
mpf_set_z(int1, str1);
// değeri print edelim.
gmp_printf("Sonuç: %.Ff\n", int1);
return 0;
}
Bu dosyayı şu şekilde derliyoruz:
gcc test.c -lgmp
Çıktı:
Sonuç: 1000000000000000000000000000000000000000000000000000000000
Teşekkürler inceleyeceğim
What is the simplest way of implementing bigint in C?
Bu soruya verilen cevapları inceleyebilirsiniz.
Oncelikle bunun cok guzel bir programlama egzersizi oldugunu soyleyeyim. En basit hali bir gunde yapilabilen, istenirse dort islem veya otesindeki matematiksel islemler eklenerek kolayca ilerletilebilen, ciktisi kafada veya hesap makinesiyle dogrulanabilen, yapmak icin basit matematik ve sayi tabanlari disinda bilgi gerektirmeyen bir egzersiz bu.
Python’a bu yuzden high level (“yuksek seviye”) programlama dili diyoruz. Bu kolayliga karsilik olarak, “bu fonksiyon 32 byte’tan fazla hafiza alani kullanmasin” veya “bu sayilar tam gereksinim olan 47 byte kadar yer kaplasin” diyemiyoruz.
Bunlar cogunlukla eskiden kalma turler. Cogu is icin islemcinin en rahat islem yaptigi (“dogal”) boyutu temsil eden int
’i kullaniyoruz. char
’in tek byte olmasi garanti (ama sayilar islem yapmak icin kullanilamiyor). int
’in yetmedigi yerlerde (>16 bit) long
, onun yetmedigi yerlerde long long
kullaniyoruz.
Tam veya minimum/maksimum boyut gereken yerlerde stdint
/inttypes’i kullanmak lazim.
Var; senin denedigin struct sisteminin hazir yapilmisi. Bu duruma/kutuphanelere “arbitrary-precision” denmekle beraber en populer ornegini @dildeolupbiten yazmis. Python da ayni seyi elle yapiyor.
Bu konuda benim de çözemediğim şeyler var. Bugün bi arkadaşım Leibniz Formülüyle pi sayısının 50. basamağına kadar hesaplayabilir misin diye sordu. Önce formülü döngüye çevirdim sonra yazdırmak istedim ama virgülden sonra 16. basamaktan sonrasını yazdıramıyorum. long double veya
bunun kullanımı nasıl?. Sadece standart C kütüphanesindeki veri tiplerini kullanarak virgülden sonra en fazla kaç hane yazdırabilirim?
Leibniz Formülü =
#include <string.h>
#include <stdio.h>
#include<locale.h>
int main() {
setlocale(LC_ALL, "Turkish");
double i,pi=0;
int x;
printf("Dizinin kaçıncı Adımını istiyorsunuz? : ");
scanf("%d",&x);
for(i=1;i<x;i=i+4){
pi+=((1/i)-(1/(i+2)))*4;
}
printf("%d. adım = %1.20lf",x, pi);
}
Bunlar da standart (C99 ve C89) veri turleri. int
, float
, long
vs. yerine kullaniyorsun. Literal’lara (bunun Turkcesi ne?) ll
veya l
ekliyorsun: 3ll
, 2.5l
.
Standart bu konuda bir sey soylemiyor. Tiplerin minimum kac hane tutabilecegini soyluyor ama haneler ikidelik hane. (log(2)/log(10)
katsayisiyla bir cevrim mevcut fakat pratikte ilk hata kacinci hanede cikar hesaplayamiyorum.) Dene ve gor.