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 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. //#define TEST_FP
  2. /* Copyright (C) 1989-1991 Apple Computer, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Warranty Information
  7. * Even though Apple has reviewed this software, Apple makes no warranty
  8. * or representation, either express or implied, with respect to this
  9. * software, its quality, accuracy, merchantability, or fitness for a
  10. * particular purpose. As a result, this software is provided "as is,"
  11. * and you, its user, are assuming the entire risk as to its quality
  12. * and accuracy.
  13. *
  14. * This code may be used and freely distributed as long as it includes
  15. * this copyright notice and the above warranty information.
  16. *
  17. * Machine-independent I/O routines for IEEE floating-point numbers.
  18. *
  19. * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  20. * happens to be infinity on IEEE machines. Unfortunately, it is
  21. * impossible to preserve NaN's in a machine-independent way.
  22. * Infinities are, however, preserved on IEEE machines.
  23. *
  24. * These routines have been tested on the following machines:
  25. * Apple Macintosh, MPW 3.1 C compiler
  26. * Apple Macintosh, THINK C compiler
  27. * Silicon Graphics IRIS, MIPS compiler
  28. * Cray X/MP and Y/MP
  29. * Digital Equipment VAX
  30. * Sequent Balance (Multiprocesor 386)
  31. * NeXT
  32. *
  33. *
  34. * Implemented by Malcolm Slaney and Ken Turkowski.
  35. *
  36. * Malcolm Slaney contributions during 1988-1990 include big- and little-
  37. * endian file I/O, conversion to and from Motorola's extended 80-bit
  38. * floating-point format, and conversions to and from IEEE single-
  39. * precision floating-point format.
  40. *
  41. * In 1991, Ken Turkowski implemented the conversions to and from
  42. * IEEE double-precision format, added more precision to the extended
  43. * conversions, and accommodated conversions involving +/- infinity,
  44. * NaN's, and denormalized numbers.
  45. */
  46. #include <stdio.h>
  47. #include <math.h>
  48. #include "ieee80.h"
  49. typedef float Single;
  50. #ifndef THINK_C
  51. typedef double Double;
  52. #else THINK_C
  53. typedef short double Double;
  54. #endif THINK_C
  55. #ifndef HUGE_VAL
  56. # define HUGE_VAL HUGE
  57. #endif HUGE_VAL
  58. /****************************************************************
  59. * The following two routines make up for deficiencies in many
  60. * compilers to convert properly between unsigned integers and
  61. * floating-point. Some compilers which have this bug are the
  62. * THINK_C compiler for the Macintosh and the C compiler for the
  63. * Silicon Graphics MIPS-based Iris.
  64. ****************************************************************/
  65. #ifdef applec /* The Apple C compiler works */
  66. # define FloatToUnsigned(f) ((unsigned long)(f))
  67. # define UnsignedToFloat(u) ((defdouble)(u))
  68. #else applec
  69. # define FloatToUnsigned(f) ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
  70. # define UnsignedToFloat(u) (((defdouble)((long)((u) - 2147483647L - 1))) + 2147483648.0)
  71. #endif applec
  72. /****************************************************************
  73. * Single precision IEEE floating-point conversion routines
  74. ****************************************************************/
  75. #define SEXP_MAX 255
  76. #define SEXP_OFFSET 127
  77. #define SEXP_SIZE 8
  78. #define SEXP_POSITION (32-SEXP_SIZE-1)
  79. defdouble
  80. ConvertFromIeeeSingle(bytes)
  81. char* bytes;
  82. {
  83. defdouble f;
  84. long mantissa, expon;
  85. long bits;
  86. bits = ((unsigned long)(bytes[0] & 0xFF) << 24)
  87. | ((unsigned long)(bytes[1] & 0xFF) << 16)
  88. | ((unsigned long)(bytes[2] & 0xFF) << 8)
  89. | (unsigned long)(bytes[3] & 0xFF); /* Assemble bytes into a long */
  90. if ((bits & 0x7FFFFFFF) == 0) {
  91. f = 0;
  92. }
  93. else {
  94. expon = (bits & 0x7F800000) >> SEXP_POSITION;
  95. if (expon == SEXP_MAX) { /* Infinity or NaN */
  96. f = HUGE_VAL; /* Map NaN's to infinity */
  97. }
  98. else {
  99. if (expon == 0) { /* Denormalized number */
  100. mantissa = (bits & 0x7fffff);
  101. f = ldexp((defdouble)mantissa, expon - SEXP_OFFSET - SEXP_POSITION + 1);
  102. }
  103. else { /* Normalized number */
  104. mantissa = (bits & 0x7fffff) + 0x800000; /* Insert hidden bit */
  105. f = ldexp((defdouble)mantissa, expon - SEXP_OFFSET - SEXP_POSITION);
  106. }
  107. }
  108. }
  109. if (bits & 0x80000000)
  110. return -f;
  111. else
  112. return f;
  113. }
  114. /****************************************************************/
  115. void
  116. ConvertToIeeeSingle(num, bytes)
  117. defdouble num;
  118. char* bytes;
  119. {
  120. long sign;
  121. register long bits;
  122. if (num < 0) { /* Can't distinguish a negative zero */
  123. sign = 0x80000000;
  124. num *= -1;
  125. } else {
  126. sign = 0;
  127. }
  128. if (num == 0) {
  129. bits = 0;
  130. }
  131. else {
  132. defdouble fMant;
  133. int expon;
  134. fMant = frexp(num, &expon);
  135. if ((expon > (SEXP_MAX-SEXP_OFFSET+1)) || !(fMant < 1)) {
  136. /* NaN's and infinities fail second test */
  137. bits = sign | 0x7F800000; /* +/- infinity */
  138. }
  139. else {
  140. long mantissa;
  141. if (expon < -(SEXP_OFFSET-2)) { /* Smaller than normalized */
  142. int shift = (SEXP_POSITION+1) + (SEXP_OFFSET-2) + expon;
  143. if (shift < 0) { /* Way too small: flush to zero */
  144. bits = sign;
  145. }
  146. else { /* Nonzero denormalized number */
  147. mantissa = (long)(fMant * (1L << shift));
  148. bits = sign | mantissa;
  149. }
  150. }
  151. else { /* Normalized number */
  152. mantissa = (long)floor(fMant * (1L << (SEXP_POSITION+1)));
  153. mantissa -= (1L << SEXP_POSITION); /* Hide MSB */
  154. bits = sign | ((long)((expon + SEXP_OFFSET - 1)) << SEXP_POSITION) | mantissa;
  155. }
  156. }
  157. }
  158. bytes[0] = bits >> 24; /* Copy to byte string */
  159. bytes[1] = bits >> 16;
  160. bytes[2] = bits >> 8;
  161. bytes[3] = bits;
  162. }
  163. /****************************************************************
  164. * Double precision IEEE floating-point conversion routines
  165. ****************************************************************/
  166. #define DEXP_MAX 2047
  167. #define DEXP_OFFSET 1023
  168. #define DEXP_SIZE 11
  169. #define DEXP_POSITION (32-DEXP_SIZE-1)
  170. defdouble
  171. ConvertFromIeeeDouble(bytes)
  172. char* bytes;
  173. {
  174. defdouble f;
  175. long mantissa, expon;
  176. unsigned long first, second;
  177. first = ((unsigned long)(bytes[0] & 0xFF) << 24)
  178. | ((unsigned long)(bytes[1] & 0xFF) << 16)
  179. | ((unsigned long)(bytes[2] & 0xFF) << 8)
  180. | (unsigned long)(bytes[3] & 0xFF);
  181. second= ((unsigned long)(bytes[4] & 0xFF) << 24)
  182. | ((unsigned long)(bytes[5] & 0xFF) << 16)
  183. | ((unsigned long)(bytes[6] & 0xFF) << 8)
  184. | (unsigned long)(bytes[7] & 0xFF);
  185. if (first == 0 && second == 0) {
  186. f = 0;
  187. }
  188. else {
  189. expon = (first & 0x7FF00000) >> DEXP_POSITION;
  190. if (expon == DEXP_MAX) { /* Infinity or NaN */
  191. f = HUGE_VAL; /* Map NaN's to infinity */
  192. }
  193. else {
  194. if (expon == 0) { /* Denormalized number */
  195. mantissa = (first & 0x000FFFFF);
  196. f = ldexp((defdouble)mantissa, expon - DEXP_OFFSET - DEXP_POSITION + 1);
  197. f += ldexp(UnsignedToFloat(second), expon - DEXP_OFFSET - DEXP_POSITION + 1 - 32);
  198. }
  199. else { /* Normalized number */
  200. mantissa = (first & 0x000FFFFF) + 0x00100000; /* Insert hidden bit */
  201. f = ldexp((defdouble)mantissa, expon - DEXP_OFFSET - DEXP_POSITION);
  202. f += ldexp(UnsignedToFloat(second), expon - DEXP_OFFSET - DEXP_POSITION - 32);
  203. }
  204. }
  205. }
  206. if (first & 0x80000000)
  207. return -f;
  208. else
  209. return f;
  210. }
  211. /****************************************************************/
  212. void
  213. ConvertToIeeeDouble(num, bytes)
  214. defdouble num;
  215. char *bytes;
  216. {
  217. long sign;
  218. long first, second;
  219. if (num < 0) { /* Can't distinguish a negative zero */
  220. sign = 0x80000000;
  221. num *= -1;
  222. } else {
  223. sign = 0;
  224. }
  225. if (num == 0) {
  226. first = 0;
  227. second = 0;
  228. }
  229. else {
  230. defdouble fMant, fsMant;
  231. int expon;
  232. fMant = frexp(num, &expon);
  233. if ((expon > (DEXP_MAX-DEXP_OFFSET+1)) || !(fMant < 1)) {
  234. /* NaN's and infinities fail second test */
  235. first = sign | 0x7FF00000; /* +/- infinity */
  236. second = 0;
  237. }
  238. else {
  239. long mantissa;
  240. if (expon < -(DEXP_OFFSET-2)) { /* Smaller than normalized */
  241. int shift = (DEXP_POSITION+1) + (DEXP_OFFSET-2) + expon;
  242. if (shift < 0) { /* Too small for something in the MS word */
  243. first = sign;
  244. shift += 32;
  245. if (shift < 0) { /* Way too small: flush to zero */
  246. second = 0;
  247. }
  248. else { /* Pretty small demorn */
  249. second = FloatToUnsigned(floor(ldexp(fMant, shift)));
  250. }
  251. }
  252. else { /* Nonzero denormalized number */
  253. fsMant = ldexp(fMant, shift);
  254. mantissa = (long)floor(fsMant);
  255. first = sign | mantissa;
  256. second = FloatToUnsigned(floor(ldexp(fsMant - mantissa, 32)));
  257. }
  258. }
  259. else { /* Normalized number */
  260. fsMant = ldexp(fMant, DEXP_POSITION+1);
  261. mantissa = (long)floor(fsMant);
  262. mantissa -= (1L << DEXP_POSITION); /* Hide MSB */
  263. fsMant -= (1L << DEXP_POSITION);
  264. first = sign | ((long)((expon + DEXP_OFFSET - 1)) << DEXP_POSITION) | mantissa;
  265. second = FloatToUnsigned(floor(ldexp(fsMant - mantissa, 32)));
  266. }
  267. }
  268. }
  269. bytes[0] = first >> 24;
  270. bytes[1] = first >> 16;
  271. bytes[2] = first >> 8;
  272. bytes[3] = first;
  273. bytes[4] = second >> 24;
  274. bytes[5] = second >> 16;
  275. bytes[6] = second >> 8;
  276. bytes[7] = second;
  277. }
  278. /****************************************************************
  279. * Extended precision IEEE floating-point conversion routines.
  280. * Extended is an 80-bit number as defined by Motorola,
  281. * with a sign bit, 15 bits of exponent (offset 16383?),
  282. * and a 64-bit mantissa, with no hidden bit.
  283. ****************************************************************/
  284. defdouble
  285. ConvertFromIeeeExtended(bytes)
  286. char* bytes;
  287. {
  288. defdouble f;
  289. long expon;
  290. unsigned long hiMant, loMant;
  291. expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
  292. hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
  293. | ((unsigned long)(bytes[3] & 0xFF) << 16)
  294. | ((unsigned long)(bytes[4] & 0xFF) << 8)
  295. | ((unsigned long)(bytes[5] & 0xFF));
  296. loMant = ((unsigned long)(bytes[6] & 0xFF) << 24)
  297. | ((unsigned long)(bytes[7] & 0xFF) << 16)
  298. | ((unsigned long)(bytes[8] & 0xFF) << 8)
  299. | ((unsigned long)(bytes[9] & 0xFF));
  300. if (expon == 0 && hiMant == 0 && loMant == 0) {
  301. f = 0;
  302. }
  303. else {
  304. if (expon == 0x7FFF) { /* Infinity or NaN */
  305. f = HUGE_VAL;
  306. }
  307. else {
  308. expon -= 16383;
  309. f = ldexp(UnsignedToFloat(hiMant), expon-=31);
  310. f += ldexp(UnsignedToFloat(loMant), expon-=32);
  311. }
  312. }
  313. if (bytes[0] & 0x80)
  314. return -f;
  315. else
  316. return f;
  317. }
  318. /****************************************************************/
  319. void
  320. ConvertToIeeeExtended(num, bytes)
  321. defdouble num;
  322. char *bytes;
  323. {
  324. int sign;
  325. int expon;
  326. defdouble fMant, fsMant;
  327. unsigned long hiMant, loMant;
  328. if (num < 0) {
  329. sign = 0x8000;
  330. num *= -1;
  331. } else {
  332. sign = 0;
  333. }
  334. if (num == 0) {
  335. expon = 0; hiMant = 0; loMant = 0;
  336. }
  337. else {
  338. fMant = frexp(num, &expon);
  339. if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
  340. expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
  341. }
  342. else { /* Finite */
  343. expon += 16382;
  344. if (expon < 0) { /* denormalized */
  345. fMant = ldexp(fMant, expon);
  346. expon = 0;
  347. }
  348. expon |= sign;
  349. fMant = ldexp(fMant, 32); fsMant = floor(fMant); hiMant = FloatToUnsigned(fsMant);
  350. fMant = ldexp(fMant - fsMant, 32); fsMant = floor(fMant); loMant = FloatToUnsigned(fsMant);
  351. }
  352. }
  353. bytes[0] = expon >> 8;
  354. bytes[1] = expon;
  355. bytes[2] = hiMant >> 24;
  356. bytes[3] = hiMant >> 16;
  357. bytes[4] = hiMant >> 8;
  358. bytes[5] = hiMant;
  359. bytes[6] = loMant >> 24;
  360. bytes[7] = loMant >> 16;
  361. bytes[8] = loMant >> 8;
  362. bytes[9] = loMant;
  363. }
  364. /****************************************************************
  365. * Testing routines for the floating-point conversions.
  366. ****************************************************************/
  367. #ifdef applec
  368. # define IEEE
  369. #endif applec
  370. #ifdef THINK_C
  371. # define IEEE
  372. #endif THINK_C
  373. #ifdef sgi
  374. # define IEEE
  375. #endif sgi
  376. #ifdef sequent
  377. # define IEEE
  378. # define LITTLE_ENDIAN
  379. #endif sequent
  380. #ifdef sun
  381. # define IEEE
  382. #endif sun
  383. #ifdef NeXT
  384. # define IEEE
  385. #endif NeXT
  386. #ifdef TEST_FP
  387. union SParts {
  388. Single s;
  389. long i;
  390. };
  391. union DParts {
  392. Double d;
  393. long i[2];
  394. };
  395. union EParts {
  396. defdouble e;
  397. short i[6];
  398. };
  399. int
  400. GetHexValue(x)
  401. register int x;
  402. {
  403. x &= 0x7F;
  404. if ('0' <= x && x <= '9')
  405. x -= '0';
  406. else if ('a' <= x && x <= 'f')
  407. x = x - 'a' + 0xA;
  408. else if ('A' <= x && x <= 'F')
  409. x = x - 'A' + 0xA;
  410. else
  411. x = 0;
  412. return(x);
  413. }
  414. void
  415. Hex2Bytes(hex, bytes)
  416. register char *hex, *bytes;
  417. {
  418. for ( ; *hex; hex += 2) {
  419. *bytes++ = (GetHexValue(hex[0]) << 4) | GetHexValue(hex[1]);
  420. if (hex[1] == 0)
  421. break; /* Guard against odd bytes */
  422. }
  423. }
  424. int
  425. GetHexSymbol(x)
  426. register int x;
  427. {
  428. x &= 0xF;
  429. if (x <= 9)
  430. x += '0';
  431. else
  432. x += 'A' - 0xA;
  433. return(x);
  434. }
  435. void
  436. Bytes2Hex(bytes, hex, nBytes)
  437. register char *bytes, *hex;
  438. register int nBytes;
  439. {
  440. for ( ; nBytes--; bytes++) {
  441. *hex++ = GetHexSymbol(*bytes >> 4);
  442. *hex++ = GetHexSymbol(*bytes);
  443. }
  444. *hex = 0;
  445. }
  446. void
  447. MaybeSwapBytes(bytes, nBytes)
  448. char* bytes;
  449. int nBytes;
  450. {
  451. #ifdef LITTLE_ENDIAN
  452. register char *p, *q, t;
  453. for (p = bytes, q = bytes+nBytes-1; p < q; p++, q--) {
  454. t = *p;
  455. *p = *q;
  456. *q = t;
  457. }
  458. #else
  459. if (bytes, nBytes); /* Just so it's used, to avoid warnings */
  460. #endif LITTLE_ENDIAN
  461. }
  462. float
  463. MachineIEEESingle(bytes)
  464. char* bytes;
  465. {
  466. float t;
  467. MaybeSwapBytes(bytes, 4);
  468. t = *((float*)(bytes));
  469. MaybeSwapBytes(bytes, 4);
  470. return (t);
  471. }
  472. Double
  473. MachineIEEEDouble(bytes)
  474. char* bytes;
  475. {
  476. Double t;
  477. MaybeSwapBytes(bytes, 8);
  478. t = *((Double*)(bytes));
  479. MaybeSwapBytes(bytes, 8);
  480. return (t);
  481. }
  482. void
  483. TestFromIeeeSingle(hex)
  484. char *hex;
  485. {
  486. defdouble f;
  487. union SParts p;
  488. char bytes[4];
  489. Hex2Bytes(hex, bytes);
  490. f = ConvertFromIeeeSingle(bytes);
  491. p.s = f;
  492. #ifdef IEEE
  493. printf("IEEE(%g) [%s] --> float(%g) [%08lX]\n",
  494. MachineIEEESingle(bytes),
  495. hex, f, p.i);
  496. #else IEEE
  497. printf("IEEE[%s] --> float(%g) [%08lX]\n", hex, f, p.i);
  498. #endif IEEE
  499. }
  500. void
  501. TestToIeeeSingle(f)
  502. defdouble f;
  503. {
  504. union SParts p;
  505. char bytes[4];
  506. char hex[8+1];
  507. p.s = f;
  508. ConvertToIeeeSingle(f, bytes);
  509. Bytes2Hex(bytes, hex, 4);
  510. #ifdef IEEE
  511. printf("float(%g) [%08lX] --> IEEE(%g) [%s]\n",
  512. f, p.i,
  513. MachineIEEESingle(bytes),
  514. hex
  515. );
  516. #else IEEE
  517. printf("float(%g) [%08lX] --> IEEE[%s]\n", f, p.i, hex);
  518. #endif IEEE
  519. }
  520. void
  521. TestFromIeeeDouble(hex)
  522. char *hex;
  523. {
  524. defdouble f;
  525. union DParts p;
  526. char bytes[8];
  527. Hex2Bytes(hex, bytes);
  528. f = ConvertFromIeeeDouble(bytes);
  529. p.d = f;
  530. #ifdef IEEE
  531. printf("IEEE(%g) [%.8s %.8s] --> double(%g) [%08lX %08lX]\n",
  532. MachineIEEEDouble(bytes),
  533. hex, hex+8, f, p.i[0], p.i[1]);
  534. #else IEEE
  535. printf("IEEE[%.8s %.8s] --> double(%g) [%08lX %08lX]\n",
  536. hex, hex+8, f, p.i[0], p.i[1]);
  537. #endif IEEE
  538. }
  539. void
  540. TestToIeeeDouble(f)
  541. defdouble f;
  542. {
  543. union DParts p;
  544. char bytes[8];
  545. char hex[16+1];
  546. p.d = f;
  547. ConvertToIeeeDouble(f, bytes);
  548. Bytes2Hex(bytes, hex, 8);
  549. #ifdef IEEE
  550. printf("double(%g) [%08lX %08lX] --> IEEE(%g) [%.8s %.8s]\n",
  551. f, p.i[0], p.i[1],
  552. MachineIEEEDouble(bytes),
  553. hex, hex+8
  554. );
  555. #else IEEE
  556. printf("double(%g) [%08lX %08lX] --> IEEE[%.8s %.8s]\n",
  557. f, p.i[0], p.i[1], hex, hex+8
  558. );
  559. #endif IEEE
  560. }
  561. void
  562. TestFromIeeeExtended(hex)
  563. char *hex;
  564. {
  565. defdouble f;
  566. union EParts p;
  567. char bytes[12];
  568. Hex2Bytes(hex, bytes);
  569. f = ConvertFromIeeeExtended(bytes);
  570. p.e = f;
  571. bytes[11] = bytes[9];
  572. bytes[10] = bytes[8];
  573. bytes[9] = bytes[7];
  574. bytes[8] = bytes[6];
  575. bytes[7] = bytes[5];
  576. bytes[6] = bytes[4];
  577. bytes[5] = bytes[3];
  578. bytes[4] = bytes[2];
  579. bytes[3] = 0;
  580. bytes[2] = 0;
  581. #if defined(applec) || defined(THINK_C)
  582. printf("IEEE(%g) [%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n",
  583. *((defdouble*)(bytes)),
  584. hex, hex+4, hex+12, f,
  585. p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF
  586. );
  587. #else /* !Macintosh */
  588. printf("IEEE[%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n",
  589. hex, hex+4, hex+12, f,
  590. p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF
  591. );
  592. #endif /* Macintosh */
  593. }
  594. void
  595. TestToIeeeExtended(f)
  596. defdouble f;
  597. {
  598. char bytes[12];
  599. char hex[24+1];
  600. ConvertToIeeeExtended(f, bytes);
  601. Bytes2Hex(bytes, hex, 10);
  602. bytes[11] = bytes[9];
  603. bytes[10] = bytes[8];
  604. bytes[9] = bytes[7];
  605. bytes[8] = bytes[6];
  606. bytes[7] = bytes[5];
  607. bytes[6] = bytes[4];
  608. bytes[5] = bytes[3];
  609. bytes[4] = bytes[2];
  610. bytes[3] = 0;
  611. bytes[2] = 0;
  612. #if defined(applec) || defined(THINK_C)
  613. printf("extended(%g) --> IEEE(%g) [%.4s %.8s %.8s]\n",
  614. f, *((defdouble*)(bytes)),
  615. hex, hex+4, hex+12
  616. );
  617. #else /* !Macintosh */
  618. printf("extended(%g) --> IEEE[%.4s %.8s %.8s]\n",
  619. f,
  620. hex, hex+4, hex+12
  621. );
  622. #endif /* Macintosh */
  623. }
  624. #include <signal.h>
  625. void SignalFPE(i, j)
  626. int i;
  627. void (*j)();
  628. {
  629. printf("[Floating Point Interrupt Caught.]\n", i, j);
  630. signal(SIGFPE, SignalFPE);
  631. }
  632. void
  633. main()
  634. {
  635. long d[3];
  636. char bytes[12];
  637. signal(SIGFPE, SignalFPE);
  638. TestFromIeeeSingle("00000000");
  639. TestFromIeeeSingle("80000000");
  640. TestFromIeeeSingle("3F800000");
  641. TestFromIeeeSingle("BF800000");
  642. TestFromIeeeSingle("40000000");
  643. TestFromIeeeSingle("C0000000");
  644. TestFromIeeeSingle("7F800000");
  645. TestFromIeeeSingle("FF800000");
  646. TestFromIeeeSingle("00800000");
  647. TestFromIeeeSingle("00400000");
  648. TestFromIeeeSingle("00000001");
  649. TestFromIeeeSingle("80000001");
  650. TestFromIeeeSingle("3F8FEDCB");
  651. TestFromIeeeSingle("7FC00100"); /* Quiet NaN(1) */
  652. TestFromIeeeSingle("7F800100"); /* Signalling NaN(1) */
  653. TestToIeeeSingle(0.0);
  654. TestToIeeeSingle(-0.0);
  655. TestToIeeeSingle(1.0);
  656. TestToIeeeSingle(-1.0);
  657. TestToIeeeSingle(2.0);
  658. TestToIeeeSingle(-2.0);
  659. TestToIeeeSingle(3.0);
  660. TestToIeeeSingle(-3.0);
  661. #if !(defined(sgi) || defined(NeXT))
  662. TestToIeeeSingle(HUGE_VAL);
  663. TestToIeeeSingle(-HUGE_VAL);
  664. #endif /* !sgi, !NeXT */
  665. #ifdef IEEE
  666. /* These only work on big-endian IEEE machines */
  667. d[0] = 0x00800000L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Smallest normalized */
  668. d[0] = 0x00400000L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Almost largest denormalized */
  669. d[0] = 0x00000001L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Smallest denormalized */
  670. d[0] = 0x00000001L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0])) * 0.5); /* Smaller than smallest denorm */
  671. d[0] = 0x3F8FEDCBL; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0])));
  672. #if !(defined(sgi) || defined(NeXT))
  673. d[0] = 0x7FC00100L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Quiet NaN(1) */
  674. d[0] = 0x7F800100L; MaybeSwapBytes((char*)d,4); TestToIeeeSingle(*((float*)(&d[0]))); /* Signalling NaN(1) */
  675. #endif /* !sgi, !NeXT */
  676. #endif IEEE
  677. TestFromIeeeDouble("0000000000000000");
  678. TestFromIeeeDouble("8000000000000000");
  679. TestFromIeeeDouble("3FF0000000000000");
  680. TestFromIeeeDouble("BFF0000000000000");
  681. TestFromIeeeDouble("4000000000000000");
  682. TestFromIeeeDouble("C000000000000000");
  683. TestFromIeeeDouble("7FF0000000000000");
  684. TestFromIeeeDouble("FFF0000000000000");
  685. TestFromIeeeDouble("0010000000000000");
  686. TestFromIeeeDouble("0008000000000000");
  687. TestFromIeeeDouble("0000000000000001");
  688. TestFromIeeeDouble("8000000000000001");
  689. TestFromIeeeDouble("3FFFEDCBA9876543");
  690. TestFromIeeeDouble("7FF8002000000000"); /* Quiet NaN(1) */
  691. TestFromIeeeDouble("7FF0002000000000"); /* Signalling NaN(1) */
  692. TestToIeeeDouble(0.0);
  693. TestToIeeeDouble(-0.0);
  694. TestToIeeeDouble(1.0);
  695. TestToIeeeDouble(-1.0);
  696. TestToIeeeDouble(2.0);
  697. TestToIeeeDouble(-2.0);
  698. TestToIeeeDouble(3.0);
  699. TestToIeeeDouble(-3.0);
  700. #if !(defined(sgi) || defined(NeXT))
  701. TestToIeeeDouble(HUGE_VAL);
  702. TestToIeeeDouble(-HUGE_VAL);
  703. #endif /* !sgi, !NeXT */
  704. #ifdef IEEE
  705. /* These only work on IEEE machines */
  706. Hex2Bytes("0010000000000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Smallest normalized */
  707. Hex2Bytes("0010000080000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Normalized, problem with unsigned */
  708. Hex2Bytes("0008000000000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Almost largest denormalized */
  709. Hex2Bytes("0000000080000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Denorm problem with unsigned */
  710. Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Smallest denormalized */
  711. Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes)) * 0.5); /* Smaller than smallest denorm */
  712. Hex2Bytes("3FFFEDCBA9876543", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* accuracy test */
  713. #if !(defined(sgi) || defined(NeXT))
  714. Hex2Bytes("7FF8002000000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Quiet NaN(1) */
  715. Hex2Bytes("7FF0002000000000", bytes); MaybeSwapBytes(bytes,8); TestToIeeeDouble(*((Double*)(bytes))); /* Signalling NaN(1) */
  716. #endif /* !sgi, !NeXT */
  717. #endif IEEE
  718. TestFromIeeeExtended("00000000000000000000"); /* +0 */
  719. TestFromIeeeExtended("80000000000000000000"); /* -0 */
  720. TestFromIeeeExtended("3FFF8000000000000000"); /* +1 */
  721. TestFromIeeeExtended("BFFF8000000000000000"); /* -1 */
  722. TestFromIeeeExtended("40008000000000000000"); /* +2 */
  723. TestFromIeeeExtended("C0008000000000000000"); /* -2 */
  724. TestFromIeeeExtended("7FFF0000000000000000"); /* +infinity */
  725. TestFromIeeeExtended("FFFF0000000000000000"); /* -infinity */
  726. TestFromIeeeExtended("7FFF8001000000000000"); /* Quiet NaN(1) */
  727. TestFromIeeeExtended("7FFF0001000000000000"); /* Signalling NaN(1) */
  728. TestFromIeeeExtended("3FFFFEDCBA9876543210"); /* accuracy test */
  729. TestToIeeeExtended(0.0);
  730. TestToIeeeExtended(-0.0);
  731. TestToIeeeExtended(1.0);
  732. TestToIeeeExtended(-1.0);
  733. TestToIeeeExtended(2.0);
  734. TestToIeeeExtended(-2.0);
  735. #if !(defined(sgi) || defined(NeXT))
  736. TestToIeeeExtended(HUGE_VAL);
  737. TestToIeeeExtended(-HUGE_VAL);
  738. #endif /* !sgi, !NeXT */
  739. #if defined(applec) || defined(THINK_C)
  740. Hex2Bytes("7FFF00008001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); /* Quiet NaN(1) */
  741. Hex2Bytes("7FFF00000001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes))); /* Signalling NaN(1) */
  742. Hex2Bytes("7FFE00008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  743. Hex2Bytes("000000008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  744. Hex2Bytes("000000000000000000000001", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  745. Hex2Bytes("3FFF0000FEDCBA9876543210", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  746. #endif /* applec, THINK_C */
  747. }
  748. /* This is the output of the test program on a big-endian IEEE machine:
  749. IEEE(0) [00000000] --> float(0) [00000000]
  750. IEEE(-0) [80000000] --> float(-0) [80000000]
  751. IEEE(1) [3F800000] --> float(1) [3F800000]
  752. IEEE(-1) [BF800000] --> float(-1) [BF800000]
  753. IEEE(2) [40000000] --> float(2) [40000000]
  754. IEEE(-2) [C0000000] --> float(-2) [C0000000]
  755. IEEE(INF) [7F800000] --> float(INF) [7F800000]
  756. IEEE(-INF) [FF800000] --> float(-INF) [FF800000]
  757. IEEE(1.17549e-38) [00800000] --> float(1.17549e-38) [00800000]
  758. IEEE(5.87747e-39) [00400000] --> float(5.87747e-39) [00400000]
  759. IEEE(1.4013e-45) [00000001] --> float(1.4013e-45) [00000001]
  760. IEEE(-1.4013e-45) [80000001] --> float(-1.4013e-45) [80000001]
  761. IEEE(1.12444) [3F8FEDCB] --> float(1.12444) [3F8FEDCB]
  762. IEEE(NAN(001)) [7FC00100] --> float(INF) [7F800000]
  763. IEEE(NAN(001)) [7F800100] --> float(INF) [7F800000]
  764. float(0) [00000000] --> IEEE(0) [00000000]
  765. float(-0) [80000000] --> IEEE(0) [00000000]
  766. float(1) [3F800000] --> IEEE(1) [3F800000]
  767. float(-1) [BF800000] --> IEEE(-1) [BF800000]
  768. float(2) [40000000] --> IEEE(2) [40000000]
  769. float(-2) [C0000000] --> IEEE(-2) [C0000000]
  770. float(3) [40400000] --> IEEE(3) [40400000]
  771. float(-3) [C0400000] --> IEEE(-3) [C0400000]
  772. float(INF) [7F800000] --> IEEE(INF) [7F800000]
  773. float(-INF) [FF800000] --> IEEE(-INF) [FF800000]
  774. float(1.17549e-38) [00800000] --> IEEE(1.17549e-38) [00800000]
  775. float(5.87747e-39) [00400000] --> IEEE(5.87747e-39) [00400000]
  776. float(1.4013e-45) [00000001] --> IEEE(1.4013e-45) [00000001]
  777. float(7.00649e-46) [00000000] --> IEEE(0) [00000000]
  778. float(1.12444) [3F8FEDCB] --> IEEE(1.12444) [3F8FEDCB]
  779. float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]
  780. float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]
  781. IEEE(0) [00000000 00000000] --> double(0) [00000000 00000000]
  782. IEEE(-0) [80000000 00000000] --> double(-0) [80000000 00000000]
  783. IEEE(1) [3FF00000 00000000] --> double(1) [3FF00000 00000000]
  784. IEEE(-1) [BFF00000 00000000] --> double(-1) [BFF00000 00000000]
  785. IEEE(2) [40000000 00000000] --> double(2) [40000000 00000000]
  786. IEEE(-2) [C0000000 00000000] --> double(-2) [C0000000 00000000]
  787. IEEE(INF) [7FF00000 00000000] --> double(INF) [7FF00000 00000000]
  788. IEEE(-INF) [FFF00000 00000000] --> double(-INF) [FFF00000 00000000]
  789. IEEE(2.22507e-308) [00100000 00000000] --> double(2.22507e-308) [00100000 00000000]
  790. IEEE(1.11254e-308) [00080000 00000000] --> double(1.11254e-308) [00080000 00000000]
  791. IEEE(4.94066e-324) [00000000 00000001] --> double(4.94066e-324) [00000000 00000001]
  792. IEEE(-4.94066e-324) [80000000 00000001] --> double(-4.94066e-324) [80000000 00000001]
  793. IEEE(1.99556) [3FFFEDCB A9876543] --> double(1.99556) [3FFFEDCB A9876543]
  794. IEEE(NAN(001)) [7FF80020 00000000] --> double(INF) [7FF00000 00000000]
  795. IEEE(NAN(001)) [7FF00020 00000000] --> double(INF) [7FF00000 00000000]
  796. double(0) [00000000 00000000] --> IEEE(0) [00000000 00000000]
  797. double(-0) [80000000 00000000] --> IEEE(0) [00000000 00000000]
  798. double(1) [3FF00000 00000000] --> IEEE(1) [3FF00000 00000000]
  799. double(-1) [BFF00000 00000000] --> IEEE(-1) [BFF00000 00000000]
  800. double(2) [40000000 00000000] --> IEEE(2) [40000000 00000000]
  801. double(-2) [C0000000 00000000] --> IEEE(-2) [C0000000 00000000]
  802. double(3) [40080000 00000000] --> IEEE(3) [40080000 00000000]
  803. double(-3) [C0080000 00000000] --> IEEE(-3) [C0080000 00000000]
  804. double(INF) [7FF00000 00000000] --> IEEE(INF) [7FF00000 00000000]
  805. double(-INF) [FFF00000 00000000] --> IEEE(-INF) [FFF00000 00000000]
  806. double(2.22507e-308) [00100000 00000000] --> IEEE(2.22507e-308) [00100000 00000000]
  807. double(2.22507e-308) [00100000 80000000] --> IEEE(2.22507e-308) [00100000 80000000]
  808. double(1.11254e-308) [00080000 00000000] --> IEEE(1.11254e-308) [00080000 00000000]
  809. double(1.061e-314) [00000000 80000000] --> IEEE(1.061e-314) [00000000 80000000]
  810. double(4.94066e-324) [00000000 00000001] --> IEEE(4.94066e-324) [00000000 00000001]
  811. double(2.47033e-324) [00000000 00000000] --> IEEE(0) [00000000 00000000]
  812. double(1.99556) [3FFFEDCB A9876543] --> IEEE(1.99556) [3FFFEDCB A9876543]
  813. double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]
  814. double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]
  815. IEEE(0) [0000 00000000 00000000] --> extended(0) [0000 00000000 00000000]
  816. IEEE(-0) [8000 00000000 00000000] --> extended(-0) [8000 00000000 00000000]
  817. IEEE(1) [3FFF 80000000 00000000] --> extended(1) [3FFF 80000000 00000000]
  818. IEEE(-1) [BFFF 80000000 00000000] --> extended(-1) [BFFF 80000000 00000000]
  819. IEEE(2) [4000 80000000 00000000] --> extended(2) [4000 80000000 00000000]
  820. IEEE(-2) [C000 80000000 00000000] --> extended(-2) [C000 80000000 00000000]
  821. IEEE(INF) [7FFF 00000000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  822. IEEE(-INF) [FFFF 00000000 00000000] --> extended(-INF) [FFFF 00000000 00000000]
  823. IEEE(NAN(001)) [7FFF 80010000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  824. IEEE(NAN(001)) [7FFF 00010000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  825. IEEE(1.99111) [3FFF FEDCBA98 76543210] --> extended(1.99111) [3FFF FEDCBA98 76543210]
  826. extended(0) --> IEEE(0) [0000 00000000 00000000]
  827. extended(-0) --> IEEE(0) [0000 00000000 00000000]
  828. extended(1) --> IEEE(1) [3FFF 80000000 00000000]
  829. extended(-1) --> IEEE(-1) [BFFF 80000000 00000000]
  830. extended(2) --> IEEE(2) [4000 80000000 00000000]
  831. extended(-2) --> IEEE(-2) [C000 80000000 00000000]
  832. extended(INF) --> IEEE(INF) [7FFF 00000000 00000000]
  833. extended(-INF) --> IEEE(-INF) [FFFF 00000000 00000000]
  834. extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]
  835. extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]
  836. extended(5.94866e+4931) --> IEEE(5.94866e+4931) [7FFE 80000000 00000000]
  837. extended(1e-4927) --> IEEE(1e-4927) [0000 80000000 00000000]
  838. extended(1e-4927) --> IEEE(1e-4927) [0000 00000000 00000001]
  839. extended(1.99111) --> IEEE(1.99111) [3FFF FEDCBA98 76543210]
  840. */
  841. #endif TEST_FP