2015-02-12 24 views
6

Başlık muhtemelen seçilmemiş, ancak bu soru için iyi bir tek satırlık özet bulamadım. Benim problemim, derleyicimin ne yaptığını anlayamıyorum ve derleyicide bir hata mı buldum yoksa C dilini anlamamı mı merak ediyorum.Bir float ile çarpıldığında imzasız bir uzun negatif olabilir mi?

  • - 1UL == ULONG_MAX
      ve bu imzasız sayılar taşma davranışı iyi
    • ürün (- 1UL) * 1.0f yüzer sol işlenen dönüştürülmesini kapsar tanımlanmış olduğundan güvenli olduğunu ve bu dönüşüm:

      Benim anlayış olmasıdır 1UL bir değişkene gelen sürece Şimdiye kadar benim derleyici, kabul eder yuvarlama hataları

    haricinde değeri (yani ULONG_MAX) korur. Geçen çıktı anlam veremiyorum

    #include <stdio.h> 
    
    int main(void) 
    { 
        unsigned long one = 1; 
        unsigned long minus_one = - one; 
        printf("%lu\n", - one);   // 18446744073709551615 
        printf("%g\n", minus_one * 1.0f); // 1.84467e+19 
        printf("%g\n", (- one) * 1.0);  // 1.84467e+19 
        printf("%g\n", (- 1UL) * 1.0f); // 1.84467e+19 
        printf("%g\n", (- one) * 1.0f); // -1 
        return 0; 
    } 
    

    : İşte benim test programı yorum olarak onun çıkışı ile vardır. Aynı optimizasyonla çeşitli optimizasyon seviyeleri ve çeşitli dil standartlarını (C90, C99 ve C11) denedim. Bir ipucu olan var mı?

    Çevre: gcc 4.8.1/Ubuntu Linux 14.04/x86-64 (I32LP64)

    Düzenleme: Sadece benim soru combination of unary minus and float conversion bir kopyası olabilir fark ettim.

  • +0

    Program, Visual Studio'da ve VM'imde beklenen çıktıyı verir (Ubuntu 10.04, gcc 4.4.3). –

    cevap

    3

    Bu gcc 4.8'de bir hata gibi görünüyor. 4.8 ile aynı davranışıma sahibim ama gcc 4.9 ve clang düzeltilmiş davranışları gösteriyor.

    +0

    Bunun bir hata olduğunu doğrulayabilir misiniz? UB olabilirim, bu durumda 4.8 bile * "doğru" *. – user694733

    +1

    @ user694733: Bu, alıntı yaptığınız öğenin sonraki paragrafında yer alır: * değeri dönüştürülen değer, temsil edilebilecek ancak tam olarak olarak gösterilemeyen değerler aralığındaysa, sonuç en yakın veya en yakın alt değerdir. gösterilebilir değer, uygulama tanımlı bir şekilde seçildi. * –

    +0

    Doğru görünüyor. Eğer bu platformda 'long' 32-bit ise, 'float' yeterli menzile sahip olmalıdır, bu durumda UB dışarıdadır. – user694733

    İlgili konular