-3

So I am trying to read data from an STL file in 4 byte increments. Each 4 byte number corresponds to a value for an x,y, or z coordinate. For my purposes, the number doesn't need to be really precise. Storing the value as a double will do. However, to read the 4 byte number, I must store it initially in a char[4].

For example if I try to read in the number "2" i get my char[4] to look like 0 0 0 64

similarly, the number 0.314286 looks like 15 -22 -96 62

After looking at this link http://www.h-schmidt.net/FloatConverter/IEEE754.html I determined that these numbers correspond to a binary representation for IEEE754. In this format, the magnitude is still the number I want (the number I want being 2 or 0.314286 for example) but I can't get my program to correctly display those values.

for example: 0 0 0 64 = 00000000 00000000 00000000 01000000 = 2 in IEEE754 NOTE: this is slightly different than the website converter in the above link because I figured the endianness may be different, however the values are still correct.

How can I convert the char[4] of 4 bytes into the actual double value that it holds? Maybe this problem is a lot easier than I think it is but I seem to be having trouble casting the value.

I read into IEEE 754 on this site http://www.cprogramming.com/tutorial/floating_point/understanding_floating_point_representation.html but I'm not sure on what way I should approach this problem.

Thank you for reading this question, I am new to this community but I appreciate any direction I can get!

Here is a code sample of how I am reading the data from a file with name stored in fname.

ifstream myFile(fname.c_str(), ios::in | ios::binary);
char triData[4] = "";
myFile.read(triData, 4);

as for the input file, its a binary STL file. Therefore viewing the file doesn't make a ton of sense to us. Here is a snippet from a file for a sphere shape.

Created by stlwrite.m 08-Oct-2014 14:15:16                                        nS·¾!©’½­Rn¿ê ¾    éçr¿ê ¾œ•Ÿ½_q¿½ä¨¾    _q¿  nS·¾!©’=­Rn¿ê ¾    éçr¿½ä¨¾    _q¿ê ¾œ•Ÿ=_q¿  £¥`¾£¥`¾^s¿ê ¾ê ¾Ly¿ê ¾Ùd“¾_q¿Ùd“¾ê ¾_q¿  ¹œe¾™½¿x¿ê ¾ê ¾Ly¿Ùd“¾ê ¾_q¿ê ¾    }0|¿  ©œe¾™½¿x¿ê ¾    }0|¿Ùd“¾ê ¾_q¿ê ¾œ•Ÿ½_q¿  ¢œe¾;™½¿x¿ê ¾    }0|¿ê ¾œ•Ÿ½_q¿ê ¾    éçr¿  ¢œe¾;™=¿x¿ê ¾    éçr¿ê ¾œ•Ÿ=_q¿ê ¾    }0|¿  ©œe¾™=¿x¿ê ¾    }0|¿ê ¾œ•Ÿ=_q¿Ùd“¾ê >_q¿  ¹œe¾™=¿x¿ê ¾    }0|¿Ùd“¾ê >_q¿ê ¾ê >Ly¿  £¥`¾£¥`>^s¿ê ¾ê >Ly¿Ùd“¾ê >_q¿ê ¾Ùd“>_q¿  !©’½nS·¾­Rn¿    ê ¾éçr¿    ½ä¨¾_q¿œ•Ÿ½ê ¾_q¿  ;™½¢œe¾¿x¿    ê ¾éçr¿œ•Ÿ½ê ¾_q¿    ê ¾}0|¿  ™½©œe¾¿x¿    ê ¾}0|¿œ•Ÿ½ê ¾_q¿ê ¾Ùd“¾_q¿  ™½¹œe¾¿x¿    ê ¾}0|¿ê ¾Ùd“¾_q¿ê ¾ê ¾Ly¿  4œ½4œ½ž~¿ê ¾ê ¾Ly¿ê ¾    }0|¿    ê ¾}0|¿  fœ½fœ½ž~¿    ê ¾}0|¿ê ¾    }0|¿        ¯H¿  fœ½4œ=ž~¿ê ¾    }0|¿ê ¾ê >Ly¿        ¯H¿  4œ½fœ=ž~¿        ¯H¿ê ¾ê >Ly¿    ê >}0|¿  ™½¹œe>¿x¿ê ¾ê >Ly¿ê ¾Ùd“>_q¿    ê >}0|¿  ™½©œe>¿x¿    ê >}0|¿ê ¾Ùd“>_q¿œ•Ÿ½ê >_q¿  ;™½¢œe>¿x¿    ê >}0|¿œ•Ÿ½ê >_q¿    ê >éçr¿  !©’½nS·>­Rn¿    ê >éçr¿œ•Ÿ½ê >_q¿    ½ä¨>_q¿  !©’=nS·¾­Rn¿    ê ¾éçr¿œ•Ÿ=ê ¾_q¿    ½ä¨¾_q¿  ;™=¢œe¾¿x¿    ê ¾éçr¿    ê ¾}0|¿œ•Ÿ=ê ¾_q¿  ™=¯œe¾¿x¿œ•Ÿ=ê ¾_q¿    ê ¾}0|¿ê >ê ¾Ly¿  +™=¸œe¾¿x¿œ•Ÿ=ê ¾_q¿ê >ê ¾Ly¿ê >Ùd“¾_q¿  4œ=fœ½ž~¿    ê ¾}0|¿        ¯H¿ê >ê ¾Ly¿  fœ=4œ½ž~¿ê >ê ¾Ly¿        ¯H¿ê >    }0|¿  fœ=fœ=ž~¿        ¯H¿    ê >}0|¿ê >    }0|¿  4œ=4œ=ž~¿ê >    }0|¿    ê >}0|¿ê >ê >Ly¿  ™=£œe>¿x¿    ê >}0|¿    ê >éçr¿ê >ê >Ly¿  ;™=½œe>¿x¿ê >ê >Ly¿    ê >éçr¿œ•Ÿ=ê >_q¿  +™=¸œe>¿x¿ê >ê >Ly¿œ•Ÿ=ê >_q¿ê >Ùd“>_q¿  !©’=nS·>­Rn¿    ê >éçr¿    ½ä¨>_q¿œ•Ÿ=ê >_q¿  £¥`>£¥`¾^s¿ê >ê ¾Ly¿Ùd“>ê ¾_q¿ê >Ùd“¾_q¿  ¹œe>™½¿x¿ê >ê ¾Ly¿ê >    }0|¿Ùd“>ê ¾_q¿  £œe>,™½¿x¿Ùd“>ê ¾_q¿ê >    }0|¿ê >    éçr¿  Ïœe>:™½¿x¿Ùd“>ê ¾_q¿ê >    éçr¿ê >œ•Ÿ½_q¿  £œe>™=¿x¿ê >    }0|¿ê >ê >Ly¿ê >    éçr¿  ¹œe>3™=¿x¿ê >    éçr¿ê >ê >Ly¿Ùd“>ê >_q¿  Ïœe>:™=¿x¿ê >    éçr¿Ùd“>ê >_q¿ê >œ•Ÿ=_q¿  £¥`>£¥`>^s¿ê >ê >Ly¿ê >Ùd“>_q¿Ùd“>ê >_q¿  nS·>!©’½­Rn¿ê >    éçr¿½ä¨>    _q¿ê >œ•Ÿ½_q¿  nS·>!©’=­Rn¿ê >    éçr¿ê >œ•Ÿ=_q¿½ä¨>    _q¿  ëS ¿OS·¾m¨I¿_ñ¾ê ¾FER¿_ñ¾É¾’$I¿¿ê ¾’$I¿  ¾ð¿¸œe¾KzR¿_ñ¾ê ¾FER¿¿ê ¾’$I¿_ñ¾ê ¾ö=]¿  ¿ð¿´œe¾JzR¿_ñ¾ê ¾ö=]¿¿ê ¾’$I¿'E¿ê ¾’$I¿  ¨        ¿7œ½JXW¿_ñ¾ê ¾ö=]¿'E¿ê ¾’$I¿_ñ¾    0æ`¿  ¤      ¿aœ½LXW¿_ñ¾    0æ`¿'E¿ê ¾’$I¿_¿    ’$I¿  ¤      ¿8œ=LXW¿_ñ¾    0æ`¿_¿    ’$I¿_ñ¾ê >ö=]¿  ¨      ¿_œ=JXW¿_ñ¾ê >ö=]¿_¿    ’$I¿'E¿ê >’$I¿  ¿ð¿·œe>JzR¿_ñ¾ê >ö=]¿'E¿ê >’$I¿_ñ¾ê >FER¿  ¾ð¿°œe>KzR¿_ñ¾ê >FER¿'E¿ê >’$I¿¿ê >’$I¿  ëS ¿OS·>m¨I¿_ñ¾ê >FER¿¿ê >’$I¿_ñ¾É>’$I¿  OS·¾ëS ¿m¨I¿ê ¾_ñ¾FER¿ê ¾¿’$I¿É¾_ñ¾’$I¿  ¢Äþ¥ÄþIXW¿ê ¾_ñ¾FER¿É¾_ñ¾’$I¿ê ¾ê ¾kŽd¿  ¥Äþ¥ÄþJXW¿ê ¾ê ¾kŽd¿É¾_ñ¾’$I¿_ñ¾É¾’$I¿  §Äþ¢ÄþKXW¿ê ¾ê ¾kŽd¿_ñ¾É¾’$I¿_ñ¾ê ¾FER¿  Ο;ƿv¾Â/b¿_ñ¾ê ¾FER¿_ñ¾ê ¾ö=]¿ê ¾ê ¾kŽd¿  ğ;±¿v¾Ã/b¿ê ¾ê ¾kŽd¿_ñ¾ê ¾ö=]¿ê ¾ê ¾‡o¿  R%Ó¾£ê¨½vBh¿ê ¾œ•Ÿ½_q¿ê ¾ê ¾‡o¿½ä¨¾    _q¿  )%Ó¾˜ê¨½Bh¿½ä¨¾    _q¿ê ¾ê ¾‡o¿_ñ¾ê ¾ö=]¿  3%Ó¾s꨽€Bh¿½ä¨¾    _q¿_ñ¾ê ¾ö=]¿_ñ¾    0æ`¿  1%Ó¾‰ê¨=~Bh¿½ä¨¾    _q¿_ñ¾    0æ`¿ê ¾œ•Ÿ=_q¿  1%Ó¾rê¨=Bh¿ê ¾œ•Ÿ=_q¿_ñ¾    0æ`¿_ñ¾ê >ö=]¿  *%Ó¾«ê¨=Bh¿ê ¾œ•Ÿ=_q¿_ñ¾ê >ö=]¿ê ¾ê >‡o¿  ğ;ȿv>Ã/b¿_ñ¾ê >ö=]¿_ñ¾ê >FER¿ê ¾ê >‡o¿  ̟;°¿v>Â/b¿ê ¾ê >‡o¿_ñ¾ê >FER¿ê ¾ê >kŽd¿  ¥Äþ¢ÄÃ>IXW¿_ñ¾ê >FER¿_ñ¾É>’$I¿ê ¾ê >kŽd¿  ¥Äþ¥ÄÃ>JXW¿ê ¾ê >kŽd¿_ñ¾É>’$I¿É¾_ñ>’$I¿  ¢Äþ§ÄÃ>KXW¿ê ¾ê >kŽd¿É¾_ñ>’$I¿ê ¾_ñ>FER¿  OS·¾ëS ?m¨I¿ê ¾_ñ>FER¿É¾_ñ>’$I¿ê ¾?’$I¿  ¸œe¾¾ð¿KzR¿ê ¾_ñ¾FER¿ê ¾_ñ¾ö=]¿ê ¾¿’$I¿  ´œe¾¿ð¿JzR¿ê ¾¿’$I¿ê ¾_ñ¾ö=]¿ê ¾'E¿’$I¿  Æ¿v¾ÎŸÍ¾Â/b¿ê ¾_ñ¾FER¿ê ¾ê ¾kŽd¿ê ¾_ñ¾ö=]¿  ²¿v¾ÄŸÍ¾Ã/b¿ê ¾_ñ¾ö=]¿ê ¾ê ¾kŽd¿ê ¾ê ¾‡o¿  7H‚¾7H‚¾–Ùn¿ê ¾Ùd“¾_q¿ê ¾ê ¾‡o¿Ùd“¾ê ¾_q¿   H‚¾$H‚¾›Ùn¿Ùd“¾ê ¾_q¿ê ¾ê ¾‡o¿ê ¾ê ¾kŽd¿  7H‚¾H‚¾˜Ùn¿Ùd“¾ê ¾_q¿ê ¾ê ¾kŽd¿ê ¾ê ¾‡o¿  ƒ3†¾`ï²½÷v¿Ùd“¾ê ¾_q¿ê ¾ê ¾‡o¿ê ¾œ•Ÿ½_q¿  ƒ3†¾`ï²=÷v¿ê ¾œ•Ÿ=_q¿ê ¾ê >‡o¿Ùd“¾ê >_q¿  7H‚¾7H‚>–Ùn¿Ùd“¾ê >_q¿ê ¾ê >‡o¿ê ¾Ùd“>_q¿  $H‚¾ H‚>›Ùn¿ê ¾Ùd“>_q¿ê ¾ê >‡o¿ê ¾ê >kŽd¿  H‚¾7H‚>˜Ùn¿ê ¾Ùd“>_q¿ê ¾ê >kŽd¿ê ¾ê >‡o¿  °¿v¾ÎŸÍ>Â/b¿ê ¾ê >kŽd¿ê ¾_ñ>FER¿ê ¾ê >‡o¿  Æ¿v¾ÄŸÍ>Ã/b¿ê ¾ê >‡o¿ê ¾_ñ>FER¿ê ¾_ñ>ö=]¿  ¸œe¾¾ð?KzR¿ê ¾_ñ>FER¿ê ¾?’$I¿ê ¾_ñ>ö=]¿  ´œe¾¿ð?JzR¿ê ¾_ñ>ö=]¿ê ¾?’$I¿ê ¾'E?’$I¿  7œ½¨      ¿JXW¿ê ¾_ñ¾ö=]¿    _ñ¾0æ`¿ê ¾'E¿’$I¿  ^œ½¤      ¿LXW¿ê ¾'E¿’$I¿    _ñ¾0æ`¿    _¿’$I¿  ‰ê¨½1%Ó¾~Bh¿    ½ä¨¾_q¿    _ñ¾0æ`¿œ•Ÿ½ê ¾_q¿  r꨽1%Ó¾Bh¿œ•Ÿ½ê ¾_q¿    _ñ¾0æ`¿ê ¾_ñ¾ö=]¿  «ê¨½*%Ó¾Bh¿œ•Ÿ½ê ¾_q¿ê ¾_ñ¾ö=]¿ê ¾ê ¾‡o¿  `ï²½ƒ3†¾÷v¿œ•Ÿ½ê ¾_q¿ê ¾ê ¾‡o¿ê ¾Ùd“¾_q¿  `ï²½ƒ3†>÷v¿ê ¾Ùd“>_q¿ê ¾ê >‡o¿œ•Ÿ½ê >_q¿  £ê¨½R%Ó>vBh¿œ•Ÿ½ê >_q¿ê ¾ê >‡o¿    ½ä¨>_q¿  ˜ê¨½)%Ó>Bh¿    ½ä¨>_q¿ê ¾ê >‡o¿ê ¾_ñ>ö=]¿  s꨽3%Ó>€Bh¿    ½ä¨>_q¿ê ¾_ñ>ö=]¿    _ñ>0æ`¿  7œ½¨     ?JXW¿ê ¾_ñ>ö=]¿ê ¾'E?’$I¿    _ñ>0æ`¿  aœ½¤      ?LXW¿    _ñ>0æ`¿ê ¾'E?’$I¿    _?’$I¿  8œ=¤      ¿LXW¿    _ñ¾0æ`¿ê >_ñ¾ö=]¿    _¿’$I¿  cœ=¨      ¿JXW¿    _¿’$I¿ê >_ñ¾ö=]¿ê >'E¿’$I¿  ‰ê¨=1%Ó¾~Bh¿    ½ä¨¾_q¿œ•Ÿ=ê ¾_q¿    _ñ¾0æ`¿  ¯ê¨=6%Ó¾~Bh¿    _ñ¾0æ`¿œ•Ÿ=ê ¾_q¿ê >ê ¾‡o¿  tê¨=*%Ó¾Bh¿    _ñ¾0æ`¿ê >ê ¾‡o¿ê >_ñ¾ö=]¿  `ï²=ƒ3†¾÷v¿œ•Ÿ=ê ¾_q¿ê >Ùd“¾_q¿ê >ê ¾‡o¿  `ï²=ƒ3†>÷v¿ê >Ùd“>_q¿œ•Ÿ=ê >_q¿ê >ê >‡o¿  £ê¨=R%Ó>vBh¿œ•Ÿ=ê >_q¿    ½ä¨>_q¿ê >ê >‡o¿  œê¨=3%Ó>€Bh¿ê >ê >‡o¿    ½ä¨>_q¿    _ñ>0æ`¿  vê¨=*%Ó>Bh¿ê >ê >‡o¿    _ñ>0æ`¿ê >_ñ>ö=]¿  8œ=¤      ?LXW¿    _ñ>0æ`¿    _?’$I¿ê >_ñ>ö=]¿  _œ=¨      ?JXW¿ê >_ñ>ö=]¿    _?’$I¿ê >'E?’$I¿  ·œe>¿ð¿JzR¿ê >_ñ¾ö=]¿ê >_ñ¾FER¿ê >'E¿’$I¿  ±œe>¾ð¿KzR¿ê >'E¿’$I¿ê >_ñ¾FER¿ê >¿’$I¿  È¿v>ğ;Ã/b¿ê >_ñ¾ö=]¿ê >ê ¾‡o¿ê >_ñ¾FER¿  ®¿v>Ο;Â/b¿ê >_ñ¾FER¿ê >ê ¾‡o¿ê >ê ¾kŽd¿  7H‚>7H‚¾–Ùn¿ê >Ùd“¾_q¿Ùd“>ê ¾_q¿ê >ê ¾‡o¿  7H‚>7H‚¾•Ùn¿ê >ê ¾‡o¿Ùd“>ê ¾_q¿ê >ê ¾‡o¿   H‚> H‚¾›Ùn¿ê >ê ¾‡o¿ê >ê ¾‡o¿ê >ê ¾kŽd¿  ƒ3†>`ï²½÷v¿Ùd“>ê ¾_q¿ê >œ•Ÿ½_q¿ê >ê ¾‡o¿  ƒ3†>`ï²=÷v¿ê >œ•Ÿ=_q¿Ùd“>ê >_q¿ê >ê >‡o¿  7H‚>7H‚>–Ùn¿Ùd“>ê >_q¿ê >Ùd“>_q¿ê >ê >‡o¿  7H‚>7H‚>•Ùn¿ê >ê >‡o¿ê >Ùd“>_q¿ê >ê >‡o¿   H‚> H‚>›Ùn¿ê >ê >‡o¿ê >ê >‡o¿ê >ê >kŽd¿  ±¿v>ÄŸÍ>Ã/b¿ê >ê >‡o¿ê >_ñ>ö=]¿ê >ê >kŽd¿  Ç¿v>ΟÍ>Â/b¿ê >ê >kŽd¿ê >_ñ>ö=]¿ê >_ñ>FER¿  ·œe>¿ð?JzR¿ê >_ñ>ö=]¿ê >'E?’$I¿ê >_ñ>FER¿  °œe>¾ð?KzR¿ê >_ñ>FER¿ê >'E?’$I¿ê >?’$I¿  OS·>ëS ¿m¨I¿ê >_ñ¾FER¿É>_ñ¾’$I¿ê >¿’$I¿  ¢ÄÃ>¥ÄþIXW¿ê >_ñ¾FER¿ê >ê ¾kŽd¿É>_ñ¾’$I¿  ¦ÄÃ

Evan

Evan
  • 1
  • 1
  • As you're new, please check [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) 1st please. – πάντα ῥεῖ May 17 '16 at 16:53
  • https://en.wikipedia.org/wiki/STL_(file_format)#Binary_STL – Evan May 17 '16 at 16:58
  • STL files are often used in 3D printing. They contain information about a 3D object. this page discusses binary STL files which is the kind I am trying to read. Sorry if my question is confusing. – Evan May 17 '16 at 16:59
  • @Evan Well, OK. Though the most missing part in your question is showing some of your code, input and a description how it's not working well. – πάντα ῥεῖ May 17 '16 at 17:02
  • It sounds like you're most of the way there. One thing that may help: `double` is 8 bytes. `float` is 4 bytes. Anyway, once you have any endian issues sorted out, the most canonical way is probably to [`memcpy`](http://en.cppreference.com/w/cpp/string/byte/memcpy) the byte array into a float (`memcpy(&outfloat, indata, sizeof(outfloat));`) and then assign the `float` to a `double`, if you need a `double`. Trying to build the `double` directly is too damn much work. – user4581301 May 17 '16 at 17:10
  • @user4581301 Thanks! I think you may be correct. What do you think about the mathematical way iEEE754 values are stored? the first bit is the sign bit, the next 8 are the exponent, and the remaining bits are called the "Mantissa". The actual value is then made by "sign * (2 ^ exponent )* mantissa". Do you think the memcpy function will understand this convertion? I guess its worth a shot either way! – Evan May 17 '16 at 17:15
  • re: `char triData[4] = "";`. You don't need the `= ""` The very next thing you do is read over top of the values you just set. Recommend testing `myFile.read(triData, 4);` for success. – user4581301 May 17 '16 at 17:16
  • memcpy worked! Thanks! @user4581301 – Evan May 17 '16 at 17:23
  • `memcpy` does not care. All it does is store a binary pattern at the destination. The compiler knows that the destination is a `float` and will interpret it accordingly. If you want to pluck out portions of a float, for example only the mantissa, it's probably easiest to `memcpy`to a `uint32_t`, use bit masks to select the piece you want and then `>>` it into position at the beginning of the `uint32_t`. – user4581301 May 17 '16 at 17:38

1 Answers1

1

Problem 1: The question reads as though OP is trying to read 4 bytes of data into a an 8 byte double. Solution to this is to use a 4 byte float, then assign to double if needed.

With data sizing out of the way, the quick solution is to read the data from the file directly into the float

float tridata;
if (inFile.read((char*)&tridata, sizeof(tridata))
{ 
    //TODO: consume tridata. May want to bounds-test tridata first.
}
else
{ 
    // TODO: Handle file IO error
}

This might not work depending on how the files were written and won't be portable across all platforms. It's most likely all that you need to do assuming the output files were generated on the same platform as the reader. It's worth trying this first to get things going.

Otherwise, read the data from the file into a generic byte buffer and convert to the local float byte ordering by swapping bytes.

Once the buffer has been ordered correctly, there are many ways to force the buffer to look like a float. Most of them will result undefined behaviour--they may work on processor and compiler X, but not Y and maybe not even reliably on X.

One thing that always works is the slow way: memcpy. With a modern compiler set to a high level of optimization it's typically not that slow.

//Open file
std::ifstream inFile(fname, std::ios::binary); // std::ios::in is implied by ifstream
// TODO: read to or seek to correct location in file
char buffer[sizeof(float)];
// read from file
if (inFile.read(buffer, sizeof(float))
{ // read 4 bytes of data from file
    float tridata;
    //TODO: flip endian as required
    std::memcpy(&tridata, buffer, sizeof(float));
    //TODO: consume tridata. May want to bounds-test tridata first.
}
else
{ // failed to read from file.
    // TODO: Handle file IO error
}
user4581301
  • 33,082
  • 7
  • 33
  • 54