SORU
8 EYLÜL 2008, PAZARTESİ


C imzalı imzasız dönüşüm - her zaman güvenli mi?

Aşağıdaki C kodu var sanırım.

unsigned int u = 1234;
int i = -5678;

unsigned int result = u   i;

Örtülü dönüşüm burada da var, ve bu kod u i tüm değerler için güvenli nedir? Öyle olsa bile (güvenli,sonuçbazı büyük pozitif sayı için taşma bu örnekte, geri bir rol verebilirimintve gerçek sonuç alırsınız.)

CEVAP
8 EYLÜL 2008, PAZARTESİ


Kısa Cevap

i olacaktırdönüştürülmüşbir işaretsiz tamsayı ekleyerek UINT_MAX 1, Daha sonra ilave olacak yürütülmekte olan imzasız değerleri, elde edilen büyük result (bağlı değerler u i).

Uzun Cevap

C99 Standardına göre:

6.3.1.8 her Zamanki aritmetik dönüşümleri

  1. Eğer her iki işlenen aynı tür varsa, o zaman başka bir dönüşüm gerekli.
  2. Her iki işlenen tamsayı türleri imzalı veya iki işaretsiz tamsayı türleri vardır, aksi takdirde daha az tamsayı dönüşüm rütbe türüyle işlenen büyük rütbe işlenen türüne dönüştürülür.
  3. Aksi halde, işlenen bu işaretsiz tamsayı türü vardır rütbe daha büyük veya eşit değerde türünün diğer işlenen, sonra da işlenen ile işaretli tamsayı türüne dönüştürülür türden işlenen imzalanmamış bir tamsayı yazın.
  4. Aksi halde, eğer bu tür işlenen imzalı tamsayı türü olabilir temsil eden tüm değerleri türü işlenen imzalanmamış bir tamsayı girin, ardından işlenen imzalanmamış bir tamsayı türü dönüştürülür türden işlenen imzalı bir tamsayı yazın.
  5. Aksi takdirde, her iki işlenen işaretsiz tamsayı türü işaretli tamsayı türü ile işlenen türüne dönüştürülür.

Sizin durumunuzda, int (u) ve imzalı int (i) bir imzasız. (3) yukarıda, her iki işlenen aynı değerde beri, 13* *atıfta gerekirdönüştürülmüşişaretsiz bir tamsayı için.

İşaretli ve işaretsiz tamsayılar 6.3.1.3

  1. Başka bir tamsayı türü değeri ise _Bool, başka dönüştürülür tamsayı değeri yeni türü tarafından temsil edilebilir, değişmez.
  2. Aksi durumda, eğer yeni tip imzasız, değer dönüştürülmüş tarafından sürekli ekleme çıkarma bir daha maksimum değeri temsil edilebilir yeni tip kadar değer aralığında yeni tip.
  3. Aksi takdirde, yeni tip imzalanır ve değer dosya içindeki temsil edilme; ya da sonuç uygulama tanımlı veya uygulama tanımlı bir sinyal ortaya çıkar.

Şimdi başvurmak için ihtiyacımız var (2) yukarıda. i UINT_MAX 1 ekleyerek imzalanmamış bir değere dönüştürülecektir. Sonuç UINT_MAX uygulama üzerinde nasıl tanımlandığını bağlı olacaktır. Büyük olacak, ama, çünkü taşma olmaz:

6.2.5 (9)

Bir hesaplama içeren imzasız işlenen asla taşma, çünkü bir sonucu olamaz tarafından temsil edilen işaretsiz tamsayı türü azalır modül sayısı tek büyük en büyük değeri temsil edilebilir sonuç yazın.

Bonus: Aritmetik Dönüşüm Yarı İŞE

#include <stdio.h>

int main(void)
{
  unsigned int plus_one = 1;
  int minus_one = -1;

  if(plus_one < minus_one)
    printf("1 < -1");
  else
    printf("boring");

  return 0;
}

Bu link bu online denemek için kullanabilirsiniz: http://codepad.org/yPhYCMFO

Bonus: Aritmetik Dönüşüm Yan Etkisi

Aritmetik dönüşüm kuralları -1, ıe: işaretsiz bir değer başlatma UINT_MAX değerini almak için kullanılabilir

unsigned int umax = -1; // umax set to UINT_MAX

Bu taşınabilir imzaladı sayı sisteminin gösterimi ne olursa olsun, dönüşüm kuralları yukarıda açıklanan nedenle garanti veriyor. Daha fazla bilgi için bu soruya bakın: Is it safe to use -1 to set all bits to true?

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • NextGenWindows

    NextGenWindo

    8 Kasım 2011
  • RogerBuckChrist

    RogerBuckChr

    9 Temmuz 2011
  • Submissions101

    Submissions1

    23 ŞUBAT 2007