Tam Sürümünü Görmek İçin : float/integer sorunu...
ergoktas
23/05/2005, 16:51
programımızın bir yerinde şöyle bir işlem yapıyoruz.Kod:
int x;
float y = 1.13;
x = 1.13*100;
buradan beklenilecegi gibi x degeri 113 degil, 112 elde ediliyor. Bu da bizim için önemli bir hata oluşturuyor.
x=1.13*100.0;
yada
x=(int)1.13f*100;
gibi denemelerde sonucu değiştirmedi.
ama mesela şöyle yaparsak :
float y = 1.13;
y*=100;
x=y;
buradan x=113 degeri elde edilebiliyor. Program Visual Studio6 da ve windows üzerinde... Acaba bir compile switch numarası mı var? yada bir precision olayımı (ve nasıl?)
fikirlerinizi bekliyorum..
x = (float) y * 100 ;
ile bu çarpımın bir float olduğunu açıkça belirtmek sorunu çözüyor..
y = 1.3f ;
atamasından sonra y = 1.29999999... gibi birşey oluyor.( float ya da double )
acehreli
23/05/2005, 23:41
ergoktas, 1.13 degerinin tUrU double'dir. Oradaki float gozume batiyor :)
Her sayi sisteminin tam olarak gosteremedigi sayilar vardir. Ornegin gunluk kullandigimiz onlu sayi sisteminde 1/3 sayisini virgulden sonra kac hane kullanirsak kullanalim tam olarak gosteremeyiz.
Bilgisayarlarin kullandigi ikili sayi sisteminde de baska sayilar tam olarak gosterilemezler. Bundan kacis yok.
Ali
ergoktas
24/05/2005, 09:40
cevaplar için tesekkürler..
x=(float) y*100; yazmak sorunu çözmüyor maalesef..
bunun bir yolu olmalı, yada round_up() vb. gibi bir fonksiyon filan olmalı diye düşünüyorum.. :confused:
yazdığım bir füze programı olsaydı, her 100 km de bir metrelik bir hatayı göze alacaktık demekki.. :D
ben en yakın tamsayı için 0.5 eklemeyi foksiyona tercih ediyorum..
x = y*100+.5;// en yakın tamsayıya gider..
yukarıdaki kodu
x = 1.13*100;// 112 oluyor
x = ( float ) 1.13 * 100 ;// 113 oluyor
için denemiştim kusura bakma :(
y koyunca o sonucu vermiyor nedense..
acehreli
25/05/2005, 00:33
ergoktas, aradigin islevler <math.h> basliginda bildirilen ceil() ve floor()... Yine de yanlis sonuclar alabilirsin, cunku hatanin degeri ne yonde degistirdigi kestirilemez.
Bu arada, bu konuda Ingilizce belge okumak isteyenler icin:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
Ali
113 yerine 112 elde etmenin nedeni veri cesitlerindeki uyusmazlik. Eger x degiskeninin veri cesidini int ten float a cevirirsen problem cozulur. Bu arada yerine gore float kullanmaya karsi degilim ancak acehreli arkadasinda yukarda uyardigi gibi floating turu veriler soz konusu oldugunda en azindan double kullanirsan cok daha saglikli bir secim yapmis olursun.
float x;
float y = 1.13;
y*=100;
x=y;
// sonucu floating olarak gostermek istiyorsan
cout<<"\nsonuc: "<<x<<endl;
/* eger sonucu integer olarak vermek istiyorsan type castingi burda yapabilirsin bu sekilde herhangi bir math fonksiyonuna ihtiyac duymadan sayi tamlamasi cozulur */
cout<<"\nsonuc: "<<(int)x<<endl;
ergoktas
25/05/2005, 17:25
acehreli:
aradigin islevler <math.h> basliginda bildirilen ceil() ve floor()... Yine de yanlis sonuclar alabilirsin, cunku hatanin degeri ne yonde degistirdigi kestirilemez.
dogru, bunu tecrübe ettim.. :hmmm:
döküman için saol..
Sabahi:
113 yerine 112 elde etmenin nedeni veri cesitlerindeki uyusmazlik. Eger x degiskeninin veri cesidini int ten float a cevirirsen problem cozulur
bu mümkün değil, değişkenlerin türlerini ni ben belirlemiyorum.. Böyle olması bir çok aplikasyon tarafından kullanılan, daha önceden belirlenmiş bir mutabakat..:(
yastasinane
25/05/2005, 23:05
"round_up gibi birsey" demissin,
Ali'nin dedigi gibi ceil veya floor isini gormez.
ama soyle bir yol izleyebilirsin;
#include <iostream>
#include <stdlib>
#include <math>
int main()
{
double tam, ondalik, sayi;
cout << "sayi girin\n";
cin >> sayi;
sayi = sayi*100;
ondalik = modf(sayi, &tam);
if(ondalik >= 0.5){
tam = tam+1;
}
cout << tam << endl;
system("PAUSE");
return 0;
}
yukardaki kodlar BORLAND'in compiler'i ile derlendi. visual 'da saniyorum std:: eklemek gerekiyor, kendine gore duzeltirsin.
yada GUI kullaniyorsan;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double tam,ondalik,sayi;
sayi=StrToFloat(Edit1->Text);
sayi = sayi*100;
ondalik = modf(sayi, &tam);
if(ondalik >= 0.5){
tam = tam+1;
}
Edit2->Text = tam;
}
acaba farkli birsey mi istedin, bilmiyorum.
yanlis anlamis olabilirim.
kolay gelsin...
acehreli
26/05/2005, 00:14
Sanirim aslinda yine <math.h> icinde bildirilen rint islevini ariyoruz: en yakin tamsayiya yuvarliyor. Ama standart C'de yokmus; sizin ortaminizda bulunabilir...
Ali
yastasinane
26/05/2005, 00:40
bende yok,
undefined function 'rint'...
bide yukarda uzatmisim heralde, aslinda amacim, elde edilen sayiyi, ondalik sayiya gore SIZ NE YAPMAK istiyorsaniz oyle yonlendirmenizdi,
ondalik = modf(sayi, &tam);
kolay gelsin...
Selam ile
Çarpımı önce float bir değişkene atayıp oradan integere aktarman sorunu çözebilir. Şöyle bir şey denedim oldu gibi
int x;
float y,z;
y=1.13;
z=y*100; //Sonuç 113.000
x=z;//Sonuç 113
printf("%d",x)
Kolay gelsin
yastasinane
26/05/2005, 01:12
ama bu;
y'ye atanan 1.1399 gibi bir rakami bile 113 olarak verecektir.
yani yuvarlama yapmayacaktir.
Zaten benim yaptığm şekli ile Ergoktas ilk mesajınde daha kısa yoldan yapmış
float y = 1.13;
y*=100;
x=y;
şeklinde. Dikkatli bakınca gördüm.
Kolay gelsin
[QUOTE=ergoktas
bu mümkün değil, değişkenlerin türlerini ni ben belirlemiyorum.. Böyle olması bir çok aplikasyon tarafından kullanılan, daha önceden belirlenmiş bir mutabakat..:([/QUOTE]
Eger ticari bir program yaziyorsaniz dogru olan bu karari veren grup ile gorusup veri uyusmazligini ortadan kaldirmaniz. Ama illa ki yok ben x i int olarak kullanmaliyim diyorsaniz kucuk bir hileye basvurabilirsiniz.
int toint(float f)
{
return (int)f;
}
Yukardaki gibi basit bir fonksiyon yazin ve x=toint(y * 100); gibi bir assignment yapin. Boylece int to int assignment yapmis olacaksiniz ve veri uyusmazligi ortadan kalktigi icin bir precision kaybi olmayacaktir.
Bu arada decimal noktadan sonra en cok iki haneye kadar gecerli bu cozum.
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.