Değişken içinde yapılan işlemde ulaşılan maks. sayı ve değişken tipi seçme

Başlatan certy, 26 Şubat 2019, 20:57:23

certy

Selamlar. Byte tipinde bir değişkenim var. Değişkeni bir işlemin sonucuna eşitliyorum. İşlem sonucuna baktığımıza sonuç byte tipi değişkenin ulaşabileceği maksimum sayı olan 255'in altında. Ancak parantez içindeki çarpma kısmında bir an da olsa byte'ın sınırlarını aşıyor. Asıl sorum şu. Şeçilecek değişken tipi o değişkenin eşitlendiği işlemin bir an da olsa ulaşacağı maksimum sayının büyüklüğüne göre mi seçilmelidir, ya da işlemin sonucunda çıkacak olan sayının büyüklüğüne göre mi seçilmelidir? (aşağıdaki sayılar tamamen uydurmadır, örnek olması için yazdım)

degisken = (130*130) / 130;
TA1USS

ahuramazda


Tagli

Burada 130*130 derleyici tarafından 16 bit bir sayıya çevrilir. Bölümün ardından da sağ taraf 16 bit olarak kalır. Bunu 8 bit bir değişkene atarsan, 16 bitlik sonucun küçük byte'ı alınır, büyük byte'ını kaybedersin. Eğer büyük byte zaten 0 ise sorun olmaz.

Sayılar işaretli olduğunda durum nasıl oluyordu emin değilim ama büyük ihtimalle, çıkan sonuç atama yapacağın değişkenin sınırları dahilinde ise sorun olmayacaktır.

130*130 kısmında derleyicinin otomatik değişken seçmesinin (galiba "literal promotion" deniyordu) bir sınırı var diye biliyorum. Çok büyük sabitleri çarparsan daha çarpma kısmında sonuç hatalı olabilir.
Gökçe Tağlıoğlu

OptimusPrime

@certy

Guzel soru. Az once bir arm derleyicide bunu deneyip asm de ne harikalar yaratiyor diye baktim. Gorununen o ki bu islemin sonucunu kendi hesaplayip degiskene sabit sayi olarak geciyor.  :du:
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

mufitsozen

Alıntı yapılan: OptimusPrime - 26 Şubat 2019, 23:25:58@certy

Guzel soru. Az once bir arm derleyicide bunu deneyip asm de ne harikalar yaratiyor diye baktim. Gorununen o ki bu islemin sonucunu kendi hesaplayip degiskene sabit sayi olarak geciyor.  :du:

@æcerty bu konu implicit type conversions diye gecer. Kullandiginiz c standardi/compilerin dokumantasyonuna bkz.

https://overiq.com/c-programming-101/implicit-type-conversion-in-c/

yada

https://www.oreilly.com/library/view/c-in-a/0596006977/ch04.html

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

OptimusPrime

@mufitsozen

implicit type conversions derleyicinin bildigi turler arasinda hesap yaparken, islemi en degerli olan tur uzerinden tamamlamasi. Halbuki sabitler uzerinde isler biraz farkli gibi gorunuyor. Mesela

u8 x = 130 * 130 / 100;

benim derleyicim bu islemi kendisi yapip x degiskenine sabit olarak deger atiyor (169). Halbuki 130 * 130 8 bitlik degiskende tasmasi lazimdi.

Hatta su islemide tasmadan yapiyor.

u8 x = (u8)130 * (u8)130 / (u8)100;

 :du:

Tekrar belirteyim. Bu islemi hedef islemciye yaptirmiyor. Kendisi hesaplayip sabit olarak geciyor.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

certy

Alıntı yapılan: OptimusPrime - 27 Şubat 2019, 18:22:51Tekrar belirteyim. Bu islemi hedef islemciye yaptirmiyor. Kendisi hesaplayip sabit olarak geciyor.

Peki ya 130 sayısı yerine sabit olmayan bir değişken var ise?  :-\
TA1USS

OptimusPrime

Senin sorun aslinda buydu sanirim.  ::)

Gorunuse gore bu olay islemcinin mimarisi ile ilgili duruyor. Eger carpma islemini yapabilecek donanimsal bir yardimcisi varsa, carpanlar dogrudan bu donanima aktariliyor. Islem sonucu ise hedef degiskenin tipine gore kirpiliyor veya kirpilmiyor. Yani hedef degiskenin icerigi degisene kadar islemci kac bitlik ise hesapda o kadar bit uzerinden yapiliyor.

Islemcinin icerisinde boyle bir donanim yoksa tip degisimi yapmakta fayda var.

Hatta bunu aliskanlik edinmektede fayda var.  :D
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

kimlenbu

sınırlara göre değişken tipi seçip type casting yapmak en güzeli.

uint8_t degisken;

degisken = (uint8_t)((uint16_t)(130*130) / 130);

bu şekilde yaparsan kafan rahat olur. Derleyici bunları otomatik yapıyor mu yapmıyor mu kafanda soru işareti kalmaz.

OptimusPrime

@kimlenbu

uint8_t degisken;

degisken = (uint16_t)(130) * 130 / 130;

Boyle daha guzel oldu  ::ok
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

mufitsozen

Alıntı yapılan: certy - 27 Şubat 2019, 19:32:52Peki ya 130 sayısı yerine sabit olmayan bir değişken var ise?  :-\

@certy

c'de literallerin de bir type tanimi vardir. Eger hicbir suffix kullanilmadi ise (130 gibi) literal int olarak kabul edilir ve ona gore daha once belirttigim sirada islem yapilir. Derleyiciler aritmetik islemi compile time'da hesaplayabiliyorsa bunun icin kod uretmezler cunku cevap sabittir.

int, long vb integer tanimlamalarin ne boyutta bilgi tutabilecekleri (minimum ve maksimum degerler) derleyicinin bir ozelligidir. Bunu da kullandiginiz derleyicinin <limits.h> dosyasindan gorebilirsiniz.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.