ieeefloat.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:29k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

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