Thread overview
April 08, 2014

int veri türünde 4 değeri 00 00 00 04 şeklinde saklanırken
short verit türünde 4 değeri 04 00 şeklinde saklanıyor.

Bunun karmaşası neden var? İleride bu tarz verilerin değişmeyeceğinin bir garantisi var mı ?
Bunlarla ilgili karmaşaya düşmemek için ne yapmak lazım?

Php deki pack işlevini D de yazmaya çalışıyorum ama bu dediğim sorunla karşılaştı şimdilik :)

Zekeriya

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

April 08, 2014
union Bint(T) {
	T i;
	char[T.sizeof] c;
};

int isBigEndian(T)(){ // 00 01 => Starts from right.
   auto bint = Bint!T(0x01);
   return bint.c[T.sizeof - 1] == 1;
}

Şöyle bir çözüm buldum. Daha iyi bir yöntem var mıdır?

Zekeriya

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

April 08, 2014

Eskiden bir başlık (http://ddili.org/forum/thread/1015) açmıştım. Burada, Ali hocam D'nin (sanırım derleme anında) bilinen bir alias'dan bahsetmişti: Endian.littleEndian

Oradan varsayılan olarak tanımlı sorgulama yapılabiliyor. Ayrıca C standartlarında verilerin bellekte nasıl durduğunu öğrenebiliyorduk. GET ve SET ile ilgili işlevler hatırlıyorum.

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

April 08, 2014

Evet az önce kontrol ettim değilmiş öyle ama o halde benim pack fonksiyonunun çalışmaması lazım. Kafam karıştı.

Şimdi elimde bir int ve ushort değeri var "Nn" değerine göre packliyorum bunları (ikiside aynı endian tipinde php.net sitesine göre) ve ushort değerini ters çevirmeden packlediğim için sıkıntı yaratıyordu çalışmıyordu program bende buna istinaden ikisinin farklı olduğunu zannettim.

Zekeriya

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

April 08, 2014

http://dlang.org/phobos/std_system.html#.endian

Evet buradaymış Salih hocam. Şu pack işine bir daha baksam iyi olur.

Şimdi anladım :) o int olarak gelen big endian sandığım veri aslında big endian değilmiş ama ben onu oluştururken ona göre oluşturuyormuşum :)

ip2int diye acemice bir fonksiyonum var

uint ip2int(string b){
	char[4] ret;
	auto spl = b.split(".");
	if(spl.length != 4) throw new Exception("Invalid IP address.");
	foreach(i, a; spl) ret[i] = to!ubyte(a);
	return *cast(uint*) ret.ptr;
}

Burada ben onu big endian değil little endian olarak çevirmişim o yüzden de hiç sorun yaşamamışım :)

Zekeriya

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

April 08, 2014

Şuydu sanırım: http://www.tysos.org/svn/trunk/tload/tloadefi/msun/src/math_private.h

Ama zaten D'nin kendi olanağı var. Özel çözüm üretmeye gerek yok :)

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

April 08, 2014

Şu an bazı kavramları karıştırdım kusura bakmayın :) little big birbirine girdi birbirlerinin yerine kullandım galiba ama birkaç güne tam anlamıyla bu kavramlar yerleşirler diye düşünüyorum.

Daha önce adını çok duymuştum ama bunların sorunu ile karşılaşmak ancak nasip oldu :)

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

April 08, 2014

Burada http://stackoverflow.com/questions/461742/how-to-convert-an-ipv4-address-into-a-integer-in-c aşağıdaki açıklamayı buldum.
Alıntı:

>

WARNING: the integers resulting from the accepted answer will be wrong, because IP addresses are in network order (big-endian), while ints are little-endian on most systems. So you must reverse the bytes before converting. See my answer for correct conversions. Also, even for IPv4, an int can't hold addresses bigger than 127.255.255.255, e.g. the broadcast address, so use a uint. – Saeb Nov 12 '12 at 20:00

Şimdi benim tanımladığım ip2int doğru endian tipinde bu açıklamaya göre o zaman değiştirmesem de olur ama olası karmaşayı önlemek amacıyla bir struct içerisinde farklı bir tür gibi mi tanımlasam? Bu sayede o veriyi pack işlevine attığımda tekrardan ters dönüp işleri karıştırmaz.

Zekeriya

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

April 08, 2014

Alıntı (zekeriyadurmus):

>

int veri türünde 4 değeri 00 00 00 04 şeklinde saklanırken
short verit türünde 4 değeri 04 00 şeklinde saklanıyor.

Emin misin?

import std.stdio;

void main()
{
   int i = 0x01020304;
   baytlarınıGöster(i);

   short s = 0x0102;
   baytlarınıGöster(s);
}

void baytlarınıGöster(T)(ref T değişken)
{
   const ubyte * baş = cast(ubyte*)&değişken;

   writefln("tür    : %s", T.stringof);
   writefln("değer  : %s", değişken);
   writefln("adres  : %s", baş);
   writef(  "baytlar: ");

   writefln("%(%02x %)", baş[0 .. T.sizeof]);

   writeln();
}

Benim Intel işlemcimdeki çıktısı:
'
tür : int
değer : 16909060
adres : 7FFF23B19538
baytlar: 04 03 02 01

tür : short
değer : 258
adres : 7FFF23B1953C
baytlar: 02 01
'

Alıntı:

>

İleride bu tarz verilerin değişmeyeceğinin bir garantisi var mı ?

Teoride, programın ileride hangi soncul ortamda çalışacağını bilemezsin. Örneğin, gelecekteki zamanda int 01 04 03 02 diye bile saklanabilir. (Değeri yine de 0x01020304 olur). Pratikte, öyle şey hiçbir zaman olmayacak. :) Ya küçük soncul ya büyük soncul...

Alıntı:

>

Bunlarla ilgili karmaşaya düşmemek için ne yapmak lazım?

std.bitmanip modülünde soncullukla ilgili işlevler var.

core.bitop içinde bayt değiş tokuş eden bswap var.

Ali

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