ieeefloat.c
上传用户:njqiyou
上传日期:2007-01-08
资源大小:574k
文件大小:28k
源码类别:

mpeg/mp3

开发平台:

C/C++

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