Thread overview
Aritmetik dönüşümler şaşırtıcı olabilir
Jun 11, 2010
Mengu
June 11, 2010

Ben olayı anlamadım. O yazdığınız kod büyük ihtimalle derleme CTFmi ne yüzünden şu hale dönüşmez mi :

int başlangıç = max(0, -1);

ve başlangıç 0 olur. Ama -1 nasıl oluyor ?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

ali hocam senden bir ricam var yanlis anlamazsan.

turkce konusundaki hassasiyetini anliyorum ve saygiyla karsiliyorum fakat her kavramin turkcelestirilmesini dogru bulmuyorum nitekim garip kelimeler cikiyor ortaya. dolayisiyla en kotu olarak turkcelestirdigin teknik terimleri parantez icinde orjinal olarak belirtirsen cok iyi olur. :)

saygilar.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Program şu:

import std.algorithm;
import std.stdio;

void main()
{
   // Boş bir satır
   char[10] satır = ' ';

   // Bir yazıyı, o satırın ilk çeyrek noktası etrafında ortalamak istiyoruz.
   int ortalanacakYer = satır.length / 4;
   string yazı = "0123456";

   // Eğer yazı yeterince uzunsa, çeyrek nokta etrafında ortalanırken başı
   // soldan taşabilir. Yani sıfırdan küçük bir indeks değeri hesaplanabilir. O
   // yüzden 'max(0' kullanarak indeksin en az 0 olmasını sağlamak istiyoruz.
   //
   // Eğer hesap sıfırdan küçükse, örneğin -1 ise, max(0, -1)'in değeri 0 olur
   // ve istediğimiz gerçekleşir.
   int başlangıç = max(0, ortalanacakYer - yazı.length / 2);

   // Ama bu denetimi geçemiyoruz! Nasıl olur?
   assert(başlangıç >= 0);      // <-- Çalışma zamanında HATA atılır

   // Sonra, yazıyı satıra şöyle yerleştirmek istiyoruz:
   foreach (i, harf; yazı) {
       satır[başlangıç + i] = harf;
   }

   writefln("|%s|", satır);
}

Şaşırtıcı bir şekilde, assert ifadesi doğru çıkmıyor. başlangıç'ın 0'dan küçük olmaMAsı gerekir. Ama öyle çıkmıyor!

Bu olay C++ ve C'de de vardır. Herhalde başka dillerde de olmalı. Nedeni, Tür Dönüşümleri dersinde kısacık değinmiş olduğum "Aritmetik dönüşümler":

http://ddili.org/ders/d/tur_donusumleri.html

Tam olarak da o başlığın altındaki 4.4 numaralı madde ile ilgili.

Yukarıdaki açıklamalar yeterli oldu mu? ;)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Belki bilmeyenler vardır diye: max, kendisine verilen parametreler içinden en büyük olanını verir. (min de en küçük olanını).

Şablonların çokuzlu parametre olanağı sayesinde de ikiden fazla parametre ile de kullanılabilir:

import std.algorithm;

void main()
{
   assert(max(0, 10, 42, 7) == 42);
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Alıntı:

>

(Hatta bazı yerlerde yanlışlıkla "çok uzlu" dediğimiz de oldu ama bence o "çok akıllı" anlamına gelir. :) )

Yanılıyorsunuz. Çok uslu çok akıllı demek. Uz, us arasında çok fark var. Uz becerikli , işe yatkın demek.(Diğer anlamıda iyi güzelmiş.) Hatta uzman'da da uz becerikli anlamında man kişi anlamında. Bizim Türkçedeki man ingilizcedeki mandan alıntı değil.(Man'a örnek: Uzman, öğretmen(büyük ünlü uyumuna uydu.) sayman, seçmen...)

Çokuzlu sözcüğünü sözcüklerde de direk gösteriyorlar. Ama Mengü Beyin dediği yinede arada sırada parantez içinde ingilizcesinide söylemekte yarar var ki zaten dershane bölümünde de bunu yapıyorsunuz.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Öncelikle, hayır, kesinlikle yanlış anlamam. (Yazın görüşünce görürsün gününü! :-p)

Türkçeler konusunda bu forumda ve başka yerlerde çok kafa yorduk, çok tartıştık, ve sonuçta bazı sözcüklerde az ya da çok beğenerek karar kıldık. Örneğin 'gösterge'den bile hâlâ emin değilim. 'işaretçi' de olurdu, 'gösterici' de...

"Çokuzlu"yu (tuple) da yeterince tartıştıktan sonra yarım gönülle kabul etmiştik. (Hatta bazı yerlerde yanlışlıkla "çok uzlu" dediğimiz de oldu ama bence o "çok akıllı" anlamına gelir. :) )

Tabii "tuple" hiç olmaz, çünkü nasıl telaffuz edileceğini bilemeyiz: İngilizce'dekine yakın olarak "tupıl" mı, ses uyumu nedeniyle "tüple" mi? :)

Hiç olmazsa, bütün uydurma :) sözcükler sözlükte bulunuyor:

http://ddili.org/sozluk.html

Yapıcı eleştirilere devam! :)

Ali

Not: "Çokuzlu parametreleri"ne şu derste değinmişim:

http://ddili.org/ders/d/sablonlar_ayrintili.html

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Şimdi baktım: "çokuzlu"yu kabul eden başka yerler de var:

http://bilisimsozlugu.net/n-tuple

Google'da tam ooon adet sayfa çıkıyor. :D

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 11, 2010

Alıntı (canalpay):

>

int başlangıç = max(0, -1);

ve başlangıç 0 olur. Ama -1 nasıl oluyor ?

Önce, hiç sorgulamadan kabul ettiğimiz aritmetik dönüşüm kavramını hatırlayalım.

Tür denetiminin derleme zamanında yapıldığı D gibi dillerde, eğer tam sağlamcı olunacaksa, short ve int'in uyumsuz oldukları düşünülebilir:

import std.stdio;

void main()
{
   short s = 7;
   int i = 42;
   writeln(typeid(s + i));  // <-- uyumsuz türlerle işlem
}

Her ne kadar türleri uyumsuz olsa da, doğal olarak short ve int tamsayıların aritmetik işlemlerde kullanılabilmelerini bekleriz. Öyle de olur...

Ayrıca, yine doğal olarak, o işlemin daha büyük olan türde yapılmasını da isteriz. O yüzden yukarıdaki programın çıktısı "int" olur; çünkü 's+i' işleminin sonucunun türü int'tir. Buraya kadar güzel...

Böyle bütün dönüşüm kurallarının dilin standardı tarafından belirlenmiş olması gerekir. Standartlar iyidir... :)

D'nin C'den aldığı aritmetik dönüşüm kuralları gereği, bir int ve uint birlikte kullanıldıklarında, sonucun türü uint'tir. (Bu, bütün tamsayı türlerin işaretli ve işaretsiz olanları arasında da böyledir; örneğin long ve ulong'da da...)

O yüzden, aşağıdaki program "uint" yazar:

import std.stdio;

void main()
{
   uint u = 7;
   int i = 42;
   writeln(typeid(u + i));
}

(Bu kural garip gelebilir; ama öyle olmasının da geçerli nedenleri vardır. Şu anda nedenini hatırlamıyorum.)

Bizim hesaba geçmeden önce bir ayrıntıya daha değinmek gerek: dizilerin .length niteliklerinin (property) değeri, işaretsiz bir türdür. O yüzden bu program "uint" yazar:

import std.stdio;

void main()
{
   int[] dizi;
   writeln(typeid(dizi.length));
}

Bu da doğaldır; çünkü uzunluk sıfırdan küçük olamayacağına göre, .length uint olabilir. Bu C++ topluluklarındaki .size() üye işlevinde ve C'nin size_t türünde de böyledir: uzunluk türü hep işaretsiz bir türdür. (Bunu eleştirenler de vardır; çünkü uzunlukların farkları alınmak istendiğinde sonuç eksi olamaz.)

Artık bizim hesaba geçebiliriz:

ortalanacakYer - yazı.length / 2

yazı.length uint olduğu için, hesabın yukarıdaki parçasının türü uint'tir. Yani, -1 olmasını beklediğimiz değer, uint eksi değer tutamayacağı için 4 küsur milyar bir değer olur.

O yüzden, max(0, 4 küsur milyar)'ın sonucu 4 küsur milyar çıkar.

Daha bitmedi! :) max'ın 4 küsur milyar olan sonucu, daha sonra 'başlangıç''ı ilklemek için kullanılıyor:

int başlangıç = ...

Tamsayılar dersinde gördüğümüz gibi, 4 küsur milyar bir int'e sığamayacağı için taşar ve eksi bir değer olur.

İşte hikaye o... :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 14, 2010

Buradaki temel sorun, işaretsiz türlerin çıkarma işleminde kullanılmaları ve sonucun eksi değer tutamadığı için beklenmedik şekilde çok büyük çıkmasıydı.

Bir öneri geldi: işaretsiz türlerin geçtiği ifadeyi çıkarma işlemi içermeyecek şekilde yazmak:

// SORUNLU!
int başlangıç = max(0, ortalanacakYer - yazı.length / 2);
// güzel
int başlangıç = ortalanacakYer - min(ortalanacakYer, yazı.length / 2);

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 16, 2010

Bir tane daha:

import std.stdio;

void main()
{
   uint sayı = 1;
   writeln("eksi işaretlisi: ", -sayı);
}

Çıktısı:

eksi işaretlisi: 4294967295

Nedeni, '-' işlecinin sonucunun türünün sağındaki ifade ile aynı olmasıymış. Türümüz uint olduğu için sonuç da -1'in uint'e atanması durumundaki gibi oluyor.

Bu bilgiyi de Aritmetik İşlemler dersine ekledim ama daha siteye koymadım.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]