سؤال

لدي هذا الجزء من التعليمات البرمجية الذي يُخرج نتائج خاطئة.

#include <stdio.h>
#include <string.h>

int main() 
{
  unsigned char bytes[4];
  float flt=0;

  bytes[0]=0xde;
  bytes[1]=0xad;
  bytes[2]=0xbe;
  bytes[3]=0xef;

  memcpy( &flt, bytes, 4);

  printf("bytes 0x%x float %e\n", flt, flt);
  return 0;
}

الإخراج الذي أحصل عليه هو

بايت 0xc0000000 تعويم -2.000001e+00

أنا أتوقع الحصول على

بايت 0xdeadbeef float -6.2598534e+18

تحرير # 1 كما أشير إلى أن النهاية يمكن أن تكون مختلفة مما يؤدي إلى ما يلي

بايت 0xefbeadde float -1.1802469e+29

ما لا أفهمه هو التحويل من float إلى unsigned int مما يؤدي إلى 0xc0000000 (الطفو في نفس بيان printf هو -2.0000 أود أن أعزوه إلى تحسين برنامج التحويل البرمجي)

كان هذا يعمل من قبل على جهاز كمبيوتر مختلف.يمكن أن يكون تغييرا في الهندسة المعمارية.

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

المحلول

إنها ليست مشكلة memcpy.

  1. float يتم تحويله دائمًا إلى double عندما مرت ... من printf، لذلك لا يمكنك الحصول على 4 بايت في معظم بنيات Intel.
  2. عندما تتوقع 0xdeadbeef في هذا الكود، تفترض أن بنيتك هي BIG endian.هناك العديد من البنى الهندسية الصغيرة، على سبيل المثال Intel x86.

نصائح أخرى

وكنت أدرك أن يطفو يتم الترويج لمضاعفة عندما تم تمريرها إلى متغير المعالم تعمل مثل printf ()؟ لذلك عندما يقول:

printf("bytes 0x%x float %e\n", flt, flt);

وتحاول معالجة ما هو في الحقيقة قيمتين 8 بايت مثل اثنين من 4 بايت القيم، وإعطاء (أعتقد) سلوك غير معرف.

وو"٪ س" في printf يتوقع عدد صحيح غير موقعة. كنت يعطيها تعويم الذي هو الحصول على تحويلها تلقائيا وهذا ليس ما تريد. تريد أن تفعل شيئا مثل:

printf("bytes 0x%x float %e\n", *((unsigned int *)&flt), flt);

وأوه، وكشخص وأشار آخر بها، إذا كنت على إلى x86 كنت لن نرى 0xdeadbeef، أشبه 0xefbeadde.

ونرى ما اذا كان هذا هو أي أفضل:

printf("bytes 0x%x float %e\n", *(int *)&flt, flt);

لرؤية تشجيع المعلمة، تغيير الإعلان من تعويم لمضاعفة. على الجهاز الخاص بي، أن يطبع:

bytes 0xefbeadde float -1.860545e+230

وو0xefbeadde هو كبير-endian لdeadbeaf. 4 بايت الأخيرة من ضعف غير محددة، وبالتالي فإن العدد المعروض بعد تعويم سوف تختلف.

ولقد ذكرت أنها عملت على جهاز كمبيوتر آخر، أي نوع من الكمبيوتر كان ذلك؟ يجب أن كنت قد endian صغيرة حيث sizeof (تعويم) == sizeof (مزدوج):)

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