/*****************************************************************************/
/*                                                                           */
/*     Project: Homework 1 - Example 1.20                                    */
/*   Copyright: Copyright © 2003. All Rights Reserved                        */
/*    Compiler: Microsoft Visual C++ .NET, Linux gcc 2.95.3                  */
/*     Company: RT Mnemonic <mnemonic@eunet.at>                              */
/*      Author: Rainer Trummer                                               */
/*        Date: November 6, 2003                                             */
/*                                                                           */
/*****************************************************************************/

#include <stdio.h>
#include <math.h>


int main( void )
{
    unsigned long n = 1, c = 126, m = 0, r, i;
    double        dm = 0.0, dr = 0.0, t;

    for( i = 0; i < 32; ++i )
    {
        if( n >= 10 )
        {
            n -= 10;
            m |= 1;
        }

        n <<= 1;
        m <<= 1;
    }

    printf( "32-bit Mantissa:   " );

    for( n = m, i = 0; i < 32; ++i )
    {
        printf( "%lu", (n & 0x80000000) >> 31 );
        n <<= 1;
    }

    while( !(m & 0x80000000) )
    {
        m <<= 1;
        --c;
    }

    m <<= 1;

    printf( "\n\n+ Normalization:   " );

    for( n = m, i = 0; i < 32; ++i )
    {
        printf( "%lu", (n & 0x80000000) >> 31 );
        n <<= 1;
    }

    r = m;
    m >>= 9;
    n = m;

    printf( "\n\n\n23-bit Chopping:   " );

    for( i = 0; i < 32; ++i )
    {
        printf( "%lu", (n & 0x80000000) >> 31 );
        n <<= 1;
    }

    if( r & 0x1ff )
    {
        r |= 0x200;
    }

    r >>= 9;
    n = r;

    printf( "\n\n23-bit Rounding:   " );

    for( i = 0; i < 32; ++i )
    {
        printf( "%lu", (n & 0x80000000) >> 31 );
        n <<= 1;
    }

    for( i = 23; i > 0; --i )
    {
        t = pow( 2.0, (double) i );
        dm += (double)(m & 1) / t;
        dr += (double)(r & 1) / t;
        m >>= 1;
        r >>= 1;
    }

    t = pow( 2.0, (double) c - 127.0 );
    dm = t * (1.0 + dm);
    dr = t * (1.0 + dr);

    printf( "\n\n\nDec 0.1 chopped:   %.30lf"
              "\n\nDec 0.1 rounded:   %.30lf", dm, dr );

    printf( "\n\n\n32-bit (float):    %.30lf", (float) 0.1 );

    printf( "\n\n\nChopping Diff.:    %.30lf"
              "\n\nRounding Diff.:    %.30lf\n\n", -(dm - 0.1), dr - 0.1 );


/*
    double f = 0.1;
    double s = 0.0;
    double d = f, t;
    char   m[64];
    bool   more = true;
    int    bits = 24, i;

    for( i = 1; i <= bits; ++i )
    {
        printf( "\n%2d   %.1lf   ", i, f );

        if( (f *= 2.0) >= 1.0 )
        {
            f -= 1.0;
            t = 1.0 / pow( 2.0, (double) i );
            s += t;
            printf( "1     %.10lf   2^-%d", t, i );
            m[i-1] = '1';
            more = false;
        }
        else
        {
            if( more )
            {
                ++bits;
            }

            printf( "0" );
            m[i-1] = '0';
        }
    }

    m[i-1] = 0;
    printf( "\n-------------------------------------\n"
            "     %.1lf  >>>    %.18lf\n\n"
            "Mantissa:        0.%s\n\n"
            "Normalized:      1.%s * 2^%d\n\n",
            d, s, m, m + bits - 23, 23 - bits );

/*
    float         f;
    double        s, c, m;
    unsigned long i, n;

    do
    {
        printf( "\nEnter floating-point number (0 to exit): " );
        scanf( "%f", &f );
        n = *(unsigned long *)& f; // prevent type conversion
        printf( "\nSign   Characteristic   Mantissa\n\n" );
        printf( "   %lu      ", (n & 0x80000000) >> 31 );
        n <<= 1;

        for( i = 0; i < 8; ++i )
        {
            printf( "%lu", (n & 0x80000000) >> 31 );
            n <<= 1;
        }

        printf( "      " );

        for( i = 0; i < 23; ++i )
        {
            printf( "%lu", (n & 0x80000000) >> 31 );
            n <<= 1;
        }

        n = *(unsigned long *)& f;
        s = 1.0 - (double)((n >> 31) << 1);
        c = pow( 2.0, (double)((n << 1) >> 24) - 127.0 );
        n = (n << 9) >> 9;
        m = 1.0;

        for( i = 23; i > 0; --i )
        {
            m += (double)(n & 1) / pow( 2.0, (double) i );
            n >>= 1;
        }

        printf( "\n\n = (-1)^S * 2^(C-127) * (1.M)"
                "\n\n = %.1lf * %.10lf * %.20lf"
                "\n\n = %.30lf\n\n",
                s, c, m, s * c * m );
    }
    while( f != 0.0 );
*/
    return( 0 );
}

// End of file.
