Advertisement
DevilDaga

IEEE754

Jan 31st, 2015
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <bitset>
  3.  
  4. using namespace std;
  5.  
  6. typedef unsigned long long bit64;
  7.  
  8. class IEEE754
  9. {
  10. public:
  11.     int EXPLENGTH, BITSIZE;
  12.     bool b_ToBits, b_Success;   // b_Success = true, if our result matches the result in memory
  13.     double num,
  14.         trueNum;                // trueNum = actual value as read from memory.
  15.     bit64 numBits,              // Consider only higher bits for 32 Bit.
  16.         trueBits;               // trueBits = actual bits read from memory.
  17.  
  18.     IEEE754 ( double num )
  19.     {
  20.         b_ToBits = true;
  21.         EXPLENGTH = 11;
  22.         BITSIZE = 64;
  23.         this->num = num;
  24.         getBits ( );
  25.         memcpy ( &trueBits, &num, sizeof trueBits );    // Read true bits from memory
  26.         b_Success = trueBits == numBits;
  27.     }
  28.  
  29.     IEEE754 ( float num )
  30.     {
  31.         b_ToBits = true;
  32.         EXPLENGTH = 8;
  33.         BITSIZE = 32;
  34.         this->num = num;
  35.         getBits ( );
  36.         memcpy ( &trueBits, &num, sizeof trueBits );    // Read true bits from memory
  37.         trueBits &= (unsigned) ( -1 );                  // Reset the lower 32 bits
  38.         b_Success = trueBits == numBits;
  39.     }
  40.  
  41.     // _Size = Number of bits
  42.     // Get the float/double value given the bits
  43.     template<size_t _Size>
  44.     IEEE754 ( bitset<_Size> bits )
  45.     {
  46.         numBits = bits.to_ullong ( );
  47.         b_ToBits = false;
  48.         if ( _Size == 32 )
  49.         {
  50.             EXPLENGTH = 8;
  51.             BITSIZE = 32;
  52.             unsigned temp = (unsigned) numBits;     // Convert to a 32 bit datatype
  53.             float fTrueNum;
  54.             memcpy ( &fTrueNum, &temp, sizeof fTrueNum );   // Read true value from memory
  55.             trueNum = fTrueNum;
  56.         }
  57.         else
  58.         {
  59.             EXPLENGTH = 11;
  60.             BITSIZE = 64;
  61.             memcpy ( &trueNum, &numBits, sizeof trueNum );  // Read true value from memory
  62.         }
  63.         for ( int i = 0; i < BITSIZE / 2; i++ )         // Reversing the array
  64.             if ( bits[ i ] != bits[ BITSIZE - 1 - i ] )
  65.                 bits = bits.flip ( i ).flip ( BITSIZE - 1 - i );
  66.         num = ( numBits != 0 );                         // 0 if all bits are 0
  67.         int exp = 0;
  68.         for ( int i = 1; i <= EXPLENGTH; i++ )          // Calculating the exponent
  69.             exp |= ( (int) ( bits[ i ] ) << ( EXPLENGTH - i ) );
  70.         for ( int i = EXPLENGTH + 1; i < BITSIZE; i++ ) // Iterate over mantissa bits
  71.             if ( bits[ i ] )
  72.                 num += pow ( 2, ( EXPLENGTH - i ) );    // Binary to fraction
  73.         exp -= ( 1UL << ( EXPLENGTH - 1 ) ) - 1;        // Subtracting the bias
  74.         num *= pow ( 2, exp );                          // Multiply by the exponent
  75.         if ( bits[ 0 ] )                                // Sign bit
  76.             num *= -1;     
  77.         float fTrueNum = (float) trueNum;
  78.         if ( BITSIZE == 32 )
  79.             b_Success = fTrueNum == (float) num;        // Convert to 32 bit and compare
  80.         else
  81.             b_Success = trueNum == num;
  82.     }
  83.  
  84.     // Calculate the bits for representing a float/double
  85.     void getBits ( )
  86.     {
  87.         numBits = 0;
  88.         if ( num == 0 )
  89.             return;
  90.         else if ( num < 0 )
  91.             numBits = 1ULL << ( BITSIZE - 1 );          // Set sign bit if negative
  92.         bit64 exp = ( 1ULL << ( EXPLENGTH - 1 ) ) - 1;  // Bias = 2 ^ ( EXPLENGTH - 1 ) - 1
  93.         double backup = abs ( num );
  94.         while ( backup >= 1 )           // Reduce a big number to a fraction
  95.         {
  96.             exp++;
  97.             backup /= 2;
  98.         }
  99.         while ( backup < 0.5 )          // In case the number is 'too small'
  100.         {
  101.             exp--;
  102.             backup *= 2;
  103.         }
  104.         bit64 mantissa = GetMantissa ( ToBits ( backup ), &exp );
  105.         // MANTISSALENGTH = ( BITSIZE - EXPLENGTH - 1 )
  106.         numBits = numBits | ( exp << ( BITSIZE - EXPLENGTH - 1 ) ) | ( mantissa >> ( EXPLENGTH + 1 ) );
  107.         //       sign bit |  exponent bits left shifted by 23/52   |   mantissa bits right shifted
  108.     }
  109.  
  110.     // Get the binary representation of a fraction
  111.     bit64 ToBits ( double n )       // Fractional part to Binary
  112.     {
  113.         bit64 bits = 0;
  114.         for ( int i = ( BITSIZE - 1 ); i != 0; i-- )    // Calculate only till BITSIZE bits
  115.         {
  116.             n *= 2;
  117.             if ( floor ( n ) == 1 )                     // n >= 1
  118.                 bits |= 1ULL << i;                      // 2 ^ i
  119.             n -= floor ( n );
  120.         }
  121.         return bits;
  122.     }
  123.  
  124.     // Calculate the bits for mantissa given the
  125.     // bits for fractional part and exponent
  126.     bit64 GetMantissa ( bit64 frac, bit64 *exp )
  127.     {
  128.         while ( !( frac & ( 1ULL << ( BITSIZE - 1 ) ) ) )   // MSB not set
  129.         {
  130.             frac <<= 1;                             // Left Shift
  131.             ( *exp )--;                             // Decrement exponent
  132.         }
  133.         ( *exp )--;                                 // Put the first set bit to the left of point
  134.         frac <<= 1;                                 // Lose the first set bit
  135.         return frac & ( ~( (bit64) ( BITSIZE == 32 ) << ( BITSIZE ) ) );
  136.         /*Fix for float, as the MSB doesn't fall off on left shift*/
  137.     }
  138.  
  139.     // Print the bits with proper spaces
  140.     template<size_t _Size>
  141.     void PrintBits ( bitset <_Size> bits )
  142.     {
  143.         cout << bits[ _Size - 1 ] << " ";
  144.         for ( int i = 1; i <= EXPLENGTH; i++ )
  145.             cout << bits[ _Size - i - 1 ];
  146.         cout << " ";
  147.         for ( int i = EXPLENGTH + 1; i < BITSIZE; i++ )
  148.             cout << bits[ _Size - i - 1 ];
  149.         cout << endl;
  150.     }
  151.  
  152.     // Display the converted result
  153.     bool Show ( )
  154.     {
  155.         if ( b_ToBits )
  156.         {
  157.             cout << BITSIZE << " Bits:\t";
  158.             if ( BITSIZE == 64 )
  159.                 PrintBits ( bitset<64> ( numBits ) );
  160.             else
  161.                 PrintBits ( bitset<32> ( numBits ) );
  162.  
  163.         }
  164.         else
  165.         {
  166.             if ( BITSIZE == 64 )
  167.                 cout << "Double:\t" << num << endl;
  168.             else
  169.                 cout << "Float:\t" << (float) num << endl;
  170.         }
  171.         return b_Success;
  172.     }
  173.  
  174. };
  175.  
  176. int main ( )                            // Driver
  177. {
  178.     IEEE754 *converter;
  179.     while ( true )
  180.     {
  181.         cout << "1:\tFloat to IEEE754\n2:\tIEEE754 to Float\n0:\tEXIT\nChoice:\t";
  182.         int choice, size;
  183.         cin >> choice;
  184.         if ( !choice )
  185.             break;
  186.         cout << "1:\t32 Bit\n2:\t64 Bit\nChoice:\t";
  187.         cin >> size;
  188.         switch ( choice )
  189.         {
  190.             case 1:
  191.                 cout << "Enter the number:\t";
  192.                 double num;
  193.                 cin >> num;
  194.                 if ( size == 1 )
  195.                     converter = new IEEE754 ( (float) num );
  196.                 else
  197.                     converter = new IEEE754 ( num );
  198.                 break;
  199.             default:
  200.             case 2:
  201.                 cout << "Enter the bits:\t";
  202.                 if ( size == 1 )
  203.                 {
  204.                     bitset<32> bits;
  205.                     cin >> bits;
  206.                     converter = new IEEE754 ( bits );
  207.                 }
  208.                 else
  209.                 {
  210.                     bitset<64> bits;
  211.                     cin >> bits;
  212.                     converter = new IEEE754 ( bits );
  213.                 }
  214.                 break;
  215.         }
  216.         cout << ( converter->Show ( ) ? "" : "Conversion Unsuccessful!" ) << endl;
  217.     }
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement