eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ieee80.c 2.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * C O N V E R T F R O M I E E E E X T E N D E D
  3. */
  4. /*
  5. * Copyright (C) 1988-1991 Apple Computer, Inc.
  6. * All rights reserved.
  7. *
  8. * Machine-independent I/O routines for IEEE floating-point numbers.
  9. *
  10. * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  11. * happens to be infinity on IEEE machines. Unfortunately, it is
  12. * impossible to preserve NaN's in a machine-independent way.
  13. * Infinities are, however, preserved on IEEE machines.
  14. *
  15. * These routines have been tested on the following machines:
  16. * Apple Macintosh, MPW 3.1 C compiler
  17. * Apple Macintosh, THINK C compiler
  18. * Silicon Graphics IRIS, MIPS compiler
  19. * Cray X/MP and Y/MP
  20. * Digital Equipment VAX
  21. *
  22. *
  23. * Implemented by Malcolm Slaney and Ken Turkowski.
  24. *
  25. * Malcolm Slaney contributions during 1988-1990 include big- and little-
  26. * endian file I/O, conversion to and from Motorola's extended 80-bit
  27. * floating-point format, and conversions to and from IEEE single-
  28. * precision floating-point format.
  29. *
  30. * In 1991, Ken Turkowski implemented the conversions to and from
  31. * IEEE double-precision format, added more precision to the extended
  32. * conversions, and accommodated conversions involving +/- infinity,
  33. * NaN's, and denormalized numbers.
  34. */
  35. #include <math.h>
  36. #ifndef HUGE_VAL
  37. # define HUGE_VAL HUGE
  38. #endif /*HUGE_VAL*/
  39. # define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
  40. /****************************************************************
  41. * Extended precision IEEE floating-point conversion routine.
  42. ****************************************************************/
  43. double ConvertFromIeeeExtended(unsigned char *bytes /* LCN */)
  44. {
  45. double f;
  46. int expon;
  47. unsigned long hiMant, loMant;
  48. expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
  49. hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
  50. | ((unsigned long)(bytes[3] & 0xFF) << 16)
  51. | ((unsigned long)(bytes[4] & 0xFF) << 8)
  52. | ((unsigned long)(bytes[5] & 0xFF));
  53. loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
  54. | ((unsigned long)(bytes[7] & 0xFF) << 16)
  55. | ((unsigned long)(bytes[8] & 0xFF) << 8)
  56. | ((unsigned long)(bytes[9] & 0xFF));
  57. if (expon == 0 && hiMant == 0 && loMant == 0) {
  58. f = 0;
  59. }
  60. else {
  61. if (expon == 0x7FFF) { /* Infinity or NaN */
  62. f = HUGE_VAL;
  63. }
  64. else {
  65. expon -= 16383;
  66. f = ldexp(UnsignedToFloat(hiMant), expon-=31);
  67. f += ldexp(UnsignedToFloat(loMant), expon-=32);
  68. }
  69. }
  70. if (bytes[0] & 0x80)
  71. return -f;
  72. else
  73. return f;
  74. }