c - الحاسب - أنواع البيانات في سي



لماذا قيمة int سالبة أكبر من int غير الموقعة؟ (4)

int x = -4 (2's complement of 4 is 1111 1100 = 252) and intigned y = 10 is (0000 1010 = 10) so 252> 10 so -4 is than than 10.

هذا السؤال لديه بالفعل إجابة هنا:

int main(void) 
{ 
     unsigned int y = 10; 
     int x = – 4; 
     if (x > y) 
        Printf("x is greater");
     else 
        Printf("y is greater"); 
     getch(); 
     return (0); 
} 

Output: x is greater

اعتقدت أن الناتج سيكون أكبر من ذلك لأنه غير موقّع. ما هو السبب وراء هذا؟


سيتم إجراء مقارنة بين قيمة موقعة وغير موقعة في "المساحة غير الموقعة". أي ، سيتم تحويل القيمة الموقعة إلى غير موقع عن طريق إضافة UINT_MAX + 1 . عند التنفيذ باستخدام مكمل 2 للقيم السالبة ، لا يتطلب الأمر معالجة خاصة للقيم تحت غطاء المحرك.

في هذا المثال ، يتم تحويل -4 إلى 0x100000000-4 = 0xFFFFFFFC وهو بوضوح > 10 .


عند مقارنة قيمتين في C ، يجب أن يكون كلاهما من نفس النوع. في هذه الحالة ( int و unsigned int ) سيتم تحويل القيمة int إلى unsigned int أولاً.

ثانيا ، يتم حساب عدد صحيح غير موقعة في C القيمة القصوى لهذا النوع + 1 (أي ، "حلقات حول" بحيث UINT_MAX + 1 هو 0 مرة أخرى والعكس صحيح). لذلك تحويل القيم السالبة إلى نتائج غير موقعة بأعداد كبيرة جدًا.

القسم ذو الصلة في المعيار يقول:

6.3.1.3 الأعداد الصحيحة الموقعة وغير الموقعة

2
وإلا ، إذا كان النوع الجديد غير موقّع ، يتم تحويل القيمة عن طريق إضافة أو طرح أكثر من الحد الأقصى للقيمة القصوى التي يمكن تمثيلها في النوع الجديد حتى تكون القيمة في نطاق النوع الجديد.


لأنه يتم ترقية القيمة int إلى unsigned int . على وجه التحديد 0xFFFFFFFC على جهاز 32 بت ، والذي هو unsigned int هو 4294967292 ، أكبر بكثير من 10

C99 6.3.1.1-p2

إذا تمكنت int من تمثيل جميع قيم النوع الأصلي (كما هو مقيد بواسطة العرض ، لحقل البتة) ، يتم تحويل القيمة إلى int؛ خلاف ذلك ، يتم تحويلها إلى int غير موقعة . وتسمى هذه الترقيات عدد صحيح. جميع الأنواع الأخرى لم تتغير عن طريق الترقيات الصحيحة.

لإجراء التحويل:

C99 6.3.1.3-p2

وإلا ، إذا كان النوع الجديد غير موقّع ، يتم تحويل القيمة عن طريق إضافة أو طرح أكثر من الحد الأقصى للقيمة القصوى التي يمكن تمثيلها في النوع الجديد حتى تكون القيمة في نطاق النوع الجديد.

والتي تعني في الأساس "إضافة UINT_MAX + 1" (كما قرأتها ، على أي حال).

فيما يتعلق سبب الترقية إلى الجانب unsigned int ؛ الأولوية:

C99 6.3.1.8-p1

... وإلا ، إذا كان المعامل الذي يحتوي على نوع صحيح غير موقعة أعلى أو يساوي رتبة نوع المعامل الآخر ، يتم تحويل المعامل ذو النوع الصحيح الموقّع إلى نوع المعامل باستخدام نوع صحيح غير موقّع.

وبخلاف ذلك ، إذا كان نوع المعامل الذي يحتوي على نوع صحيح موقّع يمكن أن يمثل جميع قيم نوع المعامل مع نوع صحيح غير موقّع ، يتم تحويل المعامل مع نوع صحيح غير موقّع إلى نوع المعامل بنوع صحيح موقّع.

الذي يقول لي int مقابل unsigned char يجب أن تعمل كما هو متوقع.

اختبار

int main()
{
    int x = -4;
    unsigned int y = 10;
    unsigned char z = 10;

    if (x > y)
        printf("x>y\n");
    else
        printf("x<y\n");

    if (x > z)
        printf("x>z\n");
    else
        printf("x<z\n");
    return 0;
}

انتاج |

x>y
x<z

حسنا انظر الى ذلك.





signed