Tipler ve sınırlar
Her kutunun bir boyu var — taşınca ne olur
Bir sayıya 1 ekleyip eksi bir sayı elde edeceksin. Kod hata vermeyecek. Bunun neden olduğunu anlayınca kitlerdeki tip seçimlerinin sebebini de anlamış olacaksın.
Önce şunu bil: her kutunun bir boyu var
Mutfakta farklı kaplar var: çay bardağı, su bardağı, sürahi. Her biri belli bir miktar alıyor. Sürahiye çay koyabilirsin ama yer israfı; bardağa sürahi dolusu su koyamazsın, taşar.
Değişkenler de öyle. Dört tip göreceksin:
| Tip | Ne tutar | Örnek | Yer |
|---|---|---|---|
int |
tam sayı | 612, -40 |
2 bayt |
float |
ondalıklı sayı | 23.5, 0.001 |
4 bayt |
bool |
doğru ya da yanlış | true, false |
1 bayt |
char |
tek karakter | 'A', '7' |
1 bayt |
Neden herkes float kullanmıyor? Çünkü kartın hafızası küçük — UNO'da 2 kilobayt. Bu sayfadaki yazı bile ondan büyük. Her bayt sayılıyor. Gereksiz büyük kap seçmek, küçük bir mutfakta her şeyi sürahide saklamak gibi.
Ama asıl mesele yer değil. Asıl mesele şu: küçük kap dolunca ne oluyor?
Kod
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz, bir fazlasini soyleyeyim:");
}
void loop() {
if (Serial.available() > 0) {
int sayi = Serial.parseInt();
while (Serial.available()) Serial.read();
int fazlasi = sayi + 1;
Serial.print(sayi);
Serial.print(" + 1 = ");
Serial.println(fazlasi);
}
}
Yükle. 5 yaz: 5 + 1 = 6. 100 yaz: 101. Çalışıyor.
Şimdi hata yap — ama kod hata vermeyecek
32767 yaz. Enter.
32767 + 1 = -32768
Eksi. Otuz iki bin yedi yüz altmış yedi artı bir, eksi otuz iki bin yedi yüz altmış sekiz.
Kod hata vermedi. Derleyici bir şey söylemedi. Kart bir uyarı basmadı. Sessizce yanlış sonuç verdi.
Sebebi: int 2 bayt. İki baytla −32768 ile 32767 arasındaki sayıları tutabiliyorsun, o kadar. 32767 kabın ağzına kadar dolu hali. Bir daha eklediğinde taşmıyor — başa dönüyor. Kilometre sayacı 999999'dan 000000'a dönüyor ya, aynı şey. Sadece burada sayaç eksiden başlıyor.
Bu bir hata değil, bir sınır. Ve kod sana söylemiyor.
Derleyicinin yakaladığı hatalar kolay: kırmızı yazı çıkıyor, düzeltiyorsun. Tehlikeli olanlar bunlar — kod çalışıyor, sonuç yanlış, kimse haber vermiyor. Sınırları bilmek senin işin.
Deneyap Kart kullanıyorsan ekranda 32768 gördün. Çünkü o kartta int 4 bayt, sınırı iki milyar. Aynı kod, iki kart, iki farklı sonuç. Sınır kodun değil, kartın. Kitlerde yazdığın kodun hangi kartta çalışacağını bilmek bu yüzden önemli.
Bir sessiz hata daha
Kodda int sayi = Serial.parseInt(); satırını şununla değiştir ve yükle:
int sayi = 3.7;
Artık klavyeden okumuyor, sayı sabit. Serial Monitor'e herhangi bir şey yazıp Enter'a bas. 3 + 1 = 4 göreceksin. Kutuya 3.7 koydun, içinde 3 var. Nokta yedi nereye gitti?
Hiçbir yere. int ondalık tutmuyor; .7'yi sessizce attı. Yine hata yok. Derleyici bazen küçük bir sarı uyarı verir, çoğu zaman onu da vermez.
Şimdi sen yaz
Aynı toplama kodunu float ile yaz. Sonra 32767 ve 3.7 için tekrar dene.
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz, bir fazlasini soyleyeyim:");
}
void loop() {
if (Serial.available() > 0) {
// ŞİMDİ SEN YAZ: sayi kutusunu float olarak ac, parseFloat ile doldur
while (Serial.available()) Serial.read();
// ŞİMDİ SEN YAZ: fazlasi kutusunu da float olarak ac
Serial.print(sayi);
Serial.print(" + 1 = ");
Serial.println(fazlasi);
}
}
🔍 İpucu 1
parseInt sayıyı tam sayı olarak okuyordu. Ondalık okumak için Serial.parseFloat() var.
🔍 İpucu 2
float sayi = Serial.parseFloat(); ve float fazlasi = sayi + 1;
✅ Cevap
float sayi = Serial.parseFloat();
float fazlasi = sayi + 1;
32767 yaz: 32768.00. Taşma yok, çünkü float'ın sınırı çok daha uzakta.
3.7 yaz: 4.70. Ondalık korundu.
Peki neden her şey float değil? İki bedeli var. Birincisi yer: iki katı. İkincisi hız: kart float ile hesabı int'e göre çok daha yavaş yapıyor — UNO'nun içinde ondalık hesap yapan bir parça yok, hepsini yazılımla taklit ediyor. Bir sensörü saniyede bin kez okuyorsan fark ediyor.
Bedava bir şey yok. Ondalık lazımsa float, değilse int.
📄 Görevin tam kodu
void setup() {
Serial.begin(9600);
Serial.println("Bir sayi yaz, bir fazlasini soyleyeyim:");
}
void loop() {
if (Serial.available() > 0) {
float sayi = Serial.parseFloat();
while (Serial.available()) Serial.read();
float fazlasi = sayi + 1;
Serial.print(sayi);
Serial.print(" + 1 = ");
Serial.println(fazlasi);
}
}
Olmadıysa
| Ne görüyorsun | Ne yap |
|---|---|
| 32767 yazınca 32768 çıkıyor, eksi değil | Deneyap Kart kullanıyorsun; orada int 4 bayt. Yukarıdaki notu oku, kodun doğru |
3.7 yazınca int ile 3 yerine 0 çıkıyor |
parseInt noktayı görünce duruyor olabilir. Serial Monitor'de 3.7 değil 3,7 yazmış olabilirsin — nokta kullan |
float ile 32768.00 yerine 32767.00 |
fazlasi'nı hâlâ int olarak açmışsın. İki kutu da float olmalı |
'parseFloat' was not declared |
serial.parseFloat yazmışsın, baş harf büyük: Serial |
Kendini test et
Soru: Bir sayacın 0'dan başlayıp her saniye 1 artıyor. int ile tuttun. Kaç saat sonra sayaç eksiye döner?
Cevabı gör
Yaklaşık dokuz saat sonra.
32767 saniye, 546 dakika, 9.1 saat. Sabah kurduğun sistem akşamüstü eksiye döner ve "kaç saniyedir çalışıyorum" sorusuna eksi bir sayı cevap verir. O sayıyı bir karşılaştırmada kullanıyorsan — "600 saniye geçtiyse sula" gibi — sistem bir daha asla sulamaz. Ve hata yok, uyarı yok.
Bu yüzden kitlerde zaman sayan yerlerde int değil unsigned long göreceksin: 4 bayt, sadece pozitif, sınırı 4 milyar. O da bir gün doluyor — 49,7 günde. Gerçekten olmuş bir kaza: Bu hata bir roketi patlattı eğitiminin 4. görevi tam olarak bunun üstüne kurulu.
Kural: bir sayı büyüyebiliyorsa sınırını hesapla. Hesaplamadıysan bir gün kendisi hatırlatır.
Kitlerde sıcaklık float, sensör okuması int. Sebebi bu görev: sıcaklık ondalıklı ve yavaş değişiyor; sensör okuması tam sayı geliyor ve saniyede binlerce kez okunuyor.
Takıldın, hata tablosu da yetmedi mi?
WhatsApp'tan sor — hangi görevdesin, ekranda ne yazıyor, devrenin fotoğrafı.