2012-04-01 30 views
13

Bu örnekte d eşittir b bu örnekte neden?garip hesaplama sonucu

unsigned int z = 176400; 
    long a = -4; 
    long b = a*z/1000; //b=4294261 
    long c = a*z; // c=-705600 
    long d = c/1000; // d =-705 

Visual Studio 2008, Windows XP, Core2Duo kullanın. Teşekkürler.

+6

... Çünkü d == c/1000. Bu gerçek bir hayat mı? – outis

+2

@crushanator Aslında, a da d'ye eşit değildir. Şunu gördün mü? –

+3

Bu örnekte 1 neden 2'ye eşit değil: 'int a = 1; int b = 2; '? –

cevap

5

int ve long'un aynı boyuta sahip olduğu bir platform kullandığınız anlaşılıyor. (Ben long eğer Gördüğünüz davranışı görmeyecektir unsigned int tüm geçerli değerler tutmak başardı gerçeğiyle bu tahminimizle.)

Bunun anlamı ifade a*z, hem a ve z yılında unsigned long'a dönüştürülür ve sonuçta unsigned long yazın. (ISO/IEC 14882: 2011, 5 [expr]/9 ... "Aksi takdirde, her iki işlenen de imzalanmış tamsayı türünde işlenenin türüne karşılık gelen işaretsiz tamsayı türüne dönüştürülür.")

c Bu ifadeyi unsigned long'dan long'a dönüştürmenin sonucu ve bu durumda, a*z'un pozitif değeri, bir long imzasında gösterilemediği için, uygulama tanımlı bir sonuçta (negatif olduğunda) sonuçlanır. c/1000, 1000, long olarak dönüştürülür ve long bölümü gerçekleştirilir (hiçbir punto amaçlanmamıştır), long (negatif olur) ile sonuçlanır ve d için depolanır. ifadeleri a*z/1000, 1000 (tip int ait bir ekspresyon) 'de

unsigned long dönüştürülür ve bölme pozitif bir sonuç, iki unsigned long arasında gerçekleştirilir. Bu sonuç, long olarak temsil edilebilir ve long'a dönüştürülüp b'a kaydedildiğinde değer değiştirilmez.

+0

Bu, MS C derleyicisindeki durumdur. – Inisheer

+0

İmzalı taşma, tanımlanmamış davranışlardır, ancak yol. –

+1

@KerrekSB: Evet, ancak bu örnekte imzalı taşma yoktur. –