On Sunday, May 5, 2013 7:30:49 AM UTC+1, (E-Mail Removed) wrote:

> On Sun, 5 May 2013 05:42:32 +0000 (UTC), glen herrmannsfeldt

>

> <(E-Mail Removed)> wrote:

>

>

>

> >Robert Wessel <(E-Mail Removed)> wrote:

>

>

> >It would complicate things. You would expect, for example, the Fortran

> >UNFORMATTED I/O to use the interchange format, though normally it is

> >expected to just copy the bits. It is even less obvious that fwrite()

> >could write the bits in a different order than they were stored in

> >memory.

>

>

>

> It's neither required to store the interchange format in memory, or

> write it to a file. But your odds of reading it from a file on a

> different IEEE-754 supporting system are better if you do write the

> interchange format. And even that's of somewhat limited value, as

> most people prefer a text format for exchanging data between systems

> (not that I necessarily agree with that, but that seems to be the

> world's preference).
I wrote this function to write IEEE floats portably.

/*

* write a double to a stream in ieee754 format regardless of host

* encoding.

* x - number to write

* fp - the stream

* bigendian - set to write big bytes first, elee write litle bytes

* first

* Returns: 0 or EOF on error

* Notes: different NaN types and negative zero not preserved.

* if the number is too big to represent it will become infinity

* if it is too small to represent it will become zero.

*/

static int fwriteieee754(double x, FILE *fp, int bigendian)

{

int shift;

unsigned long sign, exp, hibits, hilong, lowlong;

double fnorm, significand;

int expbits = 11;

int significandbits = 52;

/* zero (can't handle signed zero) */

if(x == 0)

{

hilong = 0;

lowlong = 0;

goto writedata;

}

/* infinity */

if(x > DBL_MAX)

{

hilong = 1024 + ((1<<(expbits-1)) - 1);

hilong <<= (31 - expbits);

lowlong = 0;

goto writedata;

}

/* -infinity */

if(x < -DBL_MAX)

{

hilong = 1024 + ((1<<(expbits-1)) - 1);

hilong <<= (31-expbits);

hilong |= (1 << 31);

lowlong = 0;

goto writedata;

}

/* NaN - dodgy because many compilers optimise out this test, but

*there is no portable isnan() */

if(x != x)

{

hilong = 1024 + ((1<<(expbits-1)) - 1);

hilong <<= (31 - expbits);

lowlong = 1234;

goto writedata;

}

/* get the sign */

if(x < 0) {sign = 1; fnorm = -x;}

else {sign = 0; fnorm = x;}

/* get the normalized form of f and track the exponent */

shift = 0;

while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }

while(fnorm < 1.0) { fnorm *= 2.0; shift--; }

/* check for denormalized numbers */

if(shift < -1022)

{

while(shift < -1022) {fnorm /= 2.0; shift++;}

shift = -1023;

}

/* out of range. Set to infinity */

else if(shift > 1023)

{

hilong = 1024 + ((1<<(expbits-1)) - 1);

hilong <<= (31-expbits);

hilong |= (sign << 31);

lowlong = 0;

goto writedata;

}

else

fnorm = fnorm - 1.0; /* take the significant bit off mantissa */

/* calculate the integer form of the significand */

/* hold it in a double for now */

significand = fnorm * ((1LL<<significandbits) + 0.5f);

/* get the biased exponent */

exp = shift + ((1<<(expbits-1)) - 1); /* shift + bias */

/* put the data into two longs (for convenience) */

hibits = (long) ( significand / 4294967296);

hilong = (sign << 31) | (exp << (31-expbits) ) | hibits;

x = significand - hibits * 4294967296;

lowlong = (unsigned long) (significand - hibits * 4294967296);

writedata:

/* write the bytes out to the stream */

if(bigendian)

{

fputc( (hilong >> 24) & 0xFF, fp);

fputc( (hilong >> 16) & 0xFF, fp);

fputc( (hilong >>

& 0xFF, fp);

fputc( hilong & 0xFF, fp);

fputc( (lowlong >> 24) & 0xFF, fp);

fputc( (lowlong >> 16) & 0xFF, fp);

fputc( (lowlong >>

& 0xFF, fp);

fputc( lowlong & 0xFF, fp);

}

else

{

fputc( lowlong & 0xFF, fp);

fputc( (lowlong >>

& 0xFF, fp);

fputc( (lowlong >> 16) & 0xFF, fp);

fputc( (lowlong >> 24) & 0xFF, fp);

fputc( hilong & 0xFF, fp);

fputc( (hilong >>

& 0xFF, fp);

fputc( (hilong >> 16) & 0xFF, fp);

fputc( (hilong >> 24) & 0xFF, fp);

}

return ferror(fp);

}