كيف يمكنني معرفة ما إذا كان يتم توقيع متغير صحيح C؟

StackOverflow https://stackoverflow.com/questions/1412197

  •  05-07-2019
  •  | 
  •  

سؤال

وباعتبارها ممارسة، أود أن كتابة ماكرو الذي يقول لي إذا وقعت متغير عدد صحيح. هذا ما لدي حتى الآن وأحصل على النتائج وأتوقع لو حاول هذا على متغير شار مع دول مجلس التعاون الخليجي -fsigned التفحم أو -funsigned التفحم.

#define ISVARSIGNED(V) (V = -1, (V < 0) ? 1 : 0) 

وهذا هو المحمولة؟ هل هناك طريقة للقيام بذلك دون تدمير قيمة المتغير؟

هل كانت مفيدة؟

المحلول

#define ISVARSIGNED(V)  ((V)<0 || (-V)<0 || (V-1)<0)

ولا يغير من قيمة V. الاختبار الثالث يعالج حالة حيث V == 0.

في بلدي مترجم (دول مجلس التعاون الخليجي / سيغوين) هذا يعمل لint وlong ولكن ليس لchar أو short.

#define ISVARSIGNED(V) ((V)-1<0 || -(V)-1<0)

وأيضا لا وظيفة في اختبارين.

نصائح أخرى

إذا كنت تستخدم دول مجلس التعاون الخليجي يمكنك استخدام الكلمة typeof لعدم الكتابة فوق القيمة:

#define ISVARSIGNED(V) ({ typeof (V) _V = -1; _V < 0 ? 1 : 0 })

وهذا يخلق متغير مؤقتة، _V، التي لديها نفس نوع V.

وأما بالنسبة للنقل، وأنا لا أعرف. وسوف يعمل على الجهاز مجاملة اثنين من (كل شيء يعرف أيضا باسم والتعليمات البرمجية تشغيل أي وقت مضى على في جميع الاحتمالات)، وأعتقد أنها ستعمل على المرء مجاملة وآلات وحجم التوقيع كذلك. كملاحظة جانبية، إذا كنت تستخدم typeof، قد ترغب في الإدلاء -1 إلى typeof (V) لجعله أكثر أمانا (أي أقل احتمالا لتحريك التحذيرات).

#define ISVARSIGNED(V) ((-(V) < 0) != ((V) < 0))

ودون تدمير قيمة للمتغير. ولكن لا يعمل ل0 القيم.

وماذا عن:

#define ISVARSIGNED(V) (((V)-(V)-1) < 0)

واتباع نهج مختلف لكل "جعله السلبية" الإجابات:

#define ISVARSIGNED(V) (~(V^V)<0)

وبهذه الطريقة لم يكن هناك حاجة لبعض الحالات الخاصة لقيم مختلفة من V، منذ ∀ V ∈ ℤ، V ^ V = 0.

وهذا حل بسيط ليس له آثار جانبية، بما في ذلك الاستفادة من الإشارة فقط إلى v مرة واحدة (وهو أمر مهم في ماكرو). نحن نستخدم تمديد دول مجلس التعاون الخليجي "تشير typeof" للحصول على نوع من الخامس، ثم يلقي -1 لهذا النوع:

#define IS_SIGNED_TYPE(v)   ((typeof(v))-1 <= 0)

وانها <= بدلا من مجرد <لتجنب تحذيرات المترجم لبعض الحالات (عندما تمكين).

وماذا على وجه الأرض لا تحتاج أن تكون ماكرو؟ قوالب كبيرة لهذا:

template <typename T>
bool is_signed(T) {
    static_assert(std::numeric_limits<T>::is_specialized, "Specialize std::numeric_limits<T>");
    return std::numeric_limits<T>::is_signed;
}

والتي سوف تعمل خارج مربع لجميع أنواع لا يتجزأ الأساسية. وسوف تفشل أيضا في الترجمة من الوقت على مؤشرات، الذي النسخة يستخدم فقط الطرح والمقارنة ربما لن.

تحرير : عفوا، يتطلب السؤال C. ومع ذلك، القوالب هي لطيفة الطريقة: P

وصفة مميزة من وقع / الرياضيات غير موقعة هي أنه عند تحويل حق عدد الموقعة، يتم نسخ بت الأكثر أهمية. عند تحويل عدد غير موقعة، البتات الجديدة هي 0.

#define HIGH_BIT(n) ((n) & (1 << sizeof(n) * CHAR_BITS - 1))
#define IS_SIGNED(n) (HIGH_BIT(n) ? HIGH_BIT(n >> 1) != 0 : HIGH_BIT(~n >> 1) != 0

وذلك في الأساس، يستخدم هذا الماكرو التعبير الشرطي لتحديد ما إذا تم تعيين بت عال من رقم. إذا لم تكن كذلك، الماكرو يحدد من قبل أحادي المعامل يلغي الرقم. لا نستطيع أن نفعل أي نفي الحسابي ل-0 == 0. نحن ثم تحول الحق 1 قليلا واختبار ما إذا كان وقع التمديد علامة.

وهذا يفترض 2 في الحساب تكملة، ولكن هذا عادة ما يكون الافتراض.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top