//  Floating_Point_Numbers.c
//
//  PURPOSE: 
//    This program will print out some non-standard floating point numbers and 
//    show the various implementations.
// 
//    Floating point numbers have the format
//
//      fp = S * M * 2^E
//
//    where 
//      S = Sign Bit
//      E = Exponent
//      M = Mantissa 
//   
//    They are stored as 32 bit numbers for single-precision floats in the following fashion
//   
//      fp = S            E E E E E E E E      M M M M M M M M M M M M M M M M M M M M M M M 
//           1 sign bit   8 exponent bits      23 Mantissa bits
//
//  INPUTS:
//    NONE
//
//  RETURNS:
//    NONE
// 
#include <stdio.h>              /* Standard Input Output  */
#include <math.h>               /* Standard Math stuff    */
#include <stdlib.h>		/* Standard Library stuff */
#include <string.h>

//Function for converting unsigned int to binary string
void itoa(unsigned int Value, char* Str);

//Do a union 
typedef union{
  float fp32;
  unsigned int uint32;
} Union_32;

//MAIN
int main(){

  //Declare some storage  
  Union_32 pi_union, zero_union, nan_union;

  //Make a binary string
  char  Binary_Char_Arr[36];
  char* Binary_Char_Arr_Ptr;
  
  //Convert the hexidecimal version of pi and print out the various representations
  pi_union.uint32 = 0x40490FDB;
  itoa(pi_union.uint32, Binary_Char_Arr);

  printf("Hexidecimal Represnetation of Pi stored as a float  : %08X\n\r", pi_union.uint32); 
  printf("Binary Representation of Pi stored as a float       : %s\n\r", Binary_Char_Arr);
  printf("Floating point value of Pi stored as a float        : %32.30f\n\r", pi_union.fp32);
  printf("\n\r");

  //Now print out the Zero Union
  zero_union.uint32 = 0x80000000;
  itoa(zero_union.uint32, Binary_Char_Arr);

  printf("Hexidecimal Represnetation of -0 stored as a float  : %08X\n\r", zero_union.uint32);
  printf("Binary Representation of -0 stored as a float       : %s\n\r", Binary_Char_Arr);
  printf("Floating point value of -0 stored as a float        : %32.30f\n\r", zero_union.fp32);
  printf("\n\r");

  //Now print out the NaN Union
  nan_union.uint32 = 0xFFFFFFFF;
  itoa(nan_union.uint32, Binary_Char_Arr);

  printf("Hexidecimal Represnetation of NaN stored as a float : %08X\n\r", nan_union.uint32);
  printf("Binary Representation of NaN stored as a float      : %s\n\r", Binary_Char_Arr);
  printf("Floating point value of NaN stored as a float       : %32.30f\n\r", nan_union.fp32);
  printf("\n\r");


}

//////////////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
//  itoa
//
//PURPOSE:
//  To convert a floating point number into a binary string
//
//INPUTS:
//  Value: unsigned int
//    The unsigned integer that should be converted into a binary string
//  Str: char[33];
//    A char array that has at least 33 elements (32 for the bits and 1 for the null
//    character at the end.
//
//RETURNS: 
//  NONE
//    
void itoa(unsigned int Value, char* Str){

  //Looping number and test value
  int i=0;

  //This will be the integer that will be used to hold the bit
  unsigned int a=0x00000001;
  
  for (i=0;i<32;++i){

    //Do the OR and assign the string value 
    if ((a & Value) > 0) 
      Str[31-i] = 0x31;
    else
      Str[31-i] = 0x30; 
 
    //Now bit shift to test the next bit 
    a=a<<1;

  }
  
  //Now append the null character
  Str[32] = 0x0; 

}

