PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/wrfv2_fire/external/io_grib1/WGRIB/flt2ieee.c

http://github.com/jbeezley/wrf-fire
C | 67 lines | 42 code | 11 blank | 14 comment | 7 complexity | e42867ba9af8c171ebd5ca81523568b9 MD5 | raw file
Possible License(s): AGPL-1.0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <float.h>
  5. #include "grib.h"
  6. /*
  7. * convert a float to an ieee single precision number v1.1
  8. * (big endian)
  9. * Wesley Ebisuzaki
  10. *
  11. * bugs: doesn't handle subnormal numbers
  12. * bugs: assumes length of integer >= 25 bits
  13. */
  14. int flt2ieee(float x, unsigned char *ieee) {
  15. int sign, exp;
  16. unsigned int umant;
  17. double mant;
  18. if (x == 0.0) {
  19. ieee[0] = ieee[1] = ieee[2] = ieee[3] = 0;
  20. return 0;
  21. }
  22. /* sign bit */
  23. if (x < 0.0) {
  24. sign = 128;
  25. x = -x;
  26. }
  27. else sign = 0;
  28. mant = frexp((double) x, &exp);
  29. /* 2^24 = 16777216 */
  30. umant = mant * 16777216 + 0.5;
  31. if (umant >= 16777216) {
  32. umant = umant / 2;
  33. exp++;
  34. }
  35. /* bit 24 should be a 1 .. not used in ieee format */
  36. exp = exp - 1 + 127;
  37. if (exp < 0) {
  38. /* signed zero */
  39. ieee[0] = sign;
  40. ieee[1] = ieee[2] = ieee[3] = 0;
  41. return 0;
  42. }
  43. if (exp > 255) {
  44. /* signed infinity */
  45. ieee[0] = sign + 127;
  46. ieee[1] = 128;
  47. ieee[2] = ieee[3] = 0;
  48. return 0;
  49. }
  50. /* normal number */
  51. ieee[0] = sign + (exp >> 1);
  52. ieee[3] = umant & 255;
  53. ieee[2] = (umant >> 8) & 255;
  54. ieee[1] = ((exp & 1) << 7) + ((umant >> 16) & 127);
  55. return 0;
  56. }