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

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