تحويل int إلى تعويم إلى Hex
-
21-09-2019 - |
سؤال
باستخدام ScanF ، كل رقم تم كتابته ، أود أن يطبع برنامجي سطرين: على سبيل المثال
byte order: little-endian
> 2
2 0x00000002
2.00 0x40000000
> -2
-2 0xFFFFFFFE
-2.00 0xC0000000
يمكنني الحصول عليها لطباعة 2 في Hex ، لكنني بحاجة أيضًا إلى تعويم وبالطبع لا يمكنني المسح في ذلك عندما أحتاج أيضًا إلى المسح الضوئي باعتباره INT
إذا قمت بإلقاء تعويم عندما أحاول طباعة ، أحصل على صفر. إذا قمت بالمسح الضوئي كتعويم ، أحصل على الإخراج الصحيح. لقد حاولت تحويل int إلى تعويم ، لكنه لا يزال يخرج من الصفر.
ها هو مخرجاتي حتى الآن
Int - float - hex
byte order: little-endian
>2
2 0x000002
2.00 00000000
يبدو أنني أتحول إلى غرامة تعويم لماذا لن يطبع كمسدس؟ إذا قمت بالمسح الضوئي كتعويم ، أحصل على تمثيل سداسي صحيح مثل المثال الأول. يجب أن يكون هذا شيء بسيط. أنا بحاجة إلى المسح الضوئي كأخذ في الاعتبار العشري ، فأنا أدير هذا في Cygwin
هذا ما لدي حتى الآن ..
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int HexNumber;
float convert;
printf("Int - float - hex\n");
int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
printf("\nbyte order: little-endian\n");
}
else
{
printf("\nbyte order: big-endian\n");
}
printf("\n>");
scanf("%d", &HexNumber);
printf("\n%10d ",HexNumber);
printf("%#08x",HexNumber);
convert = (float)HexNumber; // converts but prints a zero
printf("\n%10.2f ", convert);
printf("%#08x", convert); // prints zeros
return 0;
}
المحلول
جرب هذا:
int i = 2;
float f = (float)i;
printf("%#08X", *( (int*) &f ));
تعديل
corey:
دعنا نحرره من الداخل إلى الخارج:
& f = address of f = say address 0x5ca1ab1e
(int*) &f = interpret the address 0x5ca1ab1e as integer pointer
* ((int*)&f) = get the integer at address 0x5ca1ab1e
ما يلي أكثر إيجازًا ، لكن من الصعب تذكر مشغل C Language Associativity وطبقات المشغل (أفضل وضوحًا إضافيًا لبعض الأقواس المضافة ويوفر المساحة البيضاء):
printf("%#08X", *(int*)&f);
نصائح أخرى
printf("%#08x", convert); // prints zeros
هذا الخط لن يعمل لأنك تخبر printf
أنك تمر في int
(باستخدام %x
) ولكن في الواقع أنت تمره في أ float
.
ما هي نيتك مع هذا الخط؟ لإظهار التمثيل الثنائي لرقم النقطة العائمة في HEX؟ إذا كان الأمر كذلك ، فقد ترغب في تجربة شيء مثل هذا:
printf("%lx\n", *(unsigned long *)(&convert));
ما يفعله هذا الخط هو أخذ عنوان التحويل (&convert
) وهو مؤشر إلى تعويم ويلقي في مؤشر إلى فترة طويلة غير موقعة (ملاحظة: أن النوع الذي تم إلقاؤه فيه قد يكون مختلفًا اعتمادًا على حجم الطوائف وطوله على نظامك). الاخير *
هل يخلط المؤشر إلى فترة طويلة غير موقعة إلى فترة طويلة غير موقعة يتم تمريرها printf
بالنظر إلى int x ، يمكن تحويلها إلى تعويم ، ثم طباعة بايت تلك العائمة في Hex يمكن القيام بشيء مثل هذا:
show_as_float(int x) {
float xx = x;
//Edit: note that this really prints the value as a double.
printf("%f\t", xx);
unsigned char *ptr = (unsigned char *)&xx;
for (i=0; i<sizeof(float); i++)
printf("%2.2x", ptr[i]);
}
المعايير (C ++ و C99) تعطي "التوزيع الخاص" ل unsigned char
, ، لذلك من الآمن استخدامها لعرض بايت أي كائن. لم يضمن C89/90 ذلك ، لكنه كان محمولًا بشكل معقول.