You can portably serialize in IEEE-754 regardless of the native representation:
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
     * isnan() is C99, POSIX.1 only, use it if you will.
     */
    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;
    } else {
        /* take the significant bit off mantissa */
        fnorm = fnorm - 1.0;
    }
    /* 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 */
    hibits = (long)(significand / 4294967296);  /* 0x100000000 */
    hilong = (sign << 31) | (exp << (31 - expbits)) | hibits;
    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 >> 8) & 0xFF, fp);
        fputc(hilong & 0xFF, fp);
        fputc((lowlong >> 24) & 0xFF, fp);
        fputc((lowlong >> 16) & 0xFF, fp);
        fputc((lowlong >> 8) & 0xFF, fp);
        fputc(lowlong & 0xFF, fp);
    } else {
        fputc(lowlong & 0xFF, fp);
        fputc((lowlong >> 8) & 0xFF, fp);
        fputc((lowlong >> 16) & 0xFF, fp);
        fputc((lowlong >> 24) & 0xFF, fp);
        fputc(hilong & 0xFF, fp);
        fputc((hilong >> 8) & 0xFF, fp);
        fputc((hilong >> 16) & 0xFF, fp);
        fputc((hilong >> 24) & 0xFF, fp);
    }
    return ferror(fp);
}
In machines using IEEE-754 (ie. the common case), all you'll need to do to get the number is an fread(). Otherwise, decode the bytes yourself (sign * 2^(exponent-127) * 1.mantissa).
Note: when serializing in systems where the native double is more precise than the IEEE double, you might encounter off-by-one errors in the low bit.
Hope this helps.