Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <bitset>
- using namespace std;
- typedef unsigned long long bit64;
- class IEEE754
- {
- public:
- int EXPLENGTH, BITSIZE;
- bool b_ToBits, b_Success; // b_Success = true, if our result matches the result in memory
- double num,
- trueNum; // trueNum = actual value as read from memory.
- bit64 numBits, // Consider only higher bits for 32 Bit.
- trueBits; // trueBits = actual bits read from memory.
- IEEE754 ( double num )
- {
- b_ToBits = true;
- EXPLENGTH = 11;
- BITSIZE = 64;
- this->num = num;
- getBits ( );
- memcpy ( &trueBits, &num, sizeof trueBits ); // Read true bits from memory
- b_Success = trueBits == numBits;
- }
- IEEE754 ( float num )
- {
- b_ToBits = true;
- EXPLENGTH = 8;
- BITSIZE = 32;
- this->num = num;
- getBits ( );
- memcpy ( &trueBits, &num, sizeof trueBits ); // Read true bits from memory
- trueBits &= (unsigned) ( -1 ); // Reset the lower 32 bits
- b_Success = trueBits == numBits;
- }
- // _Size = Number of bits
- // Get the float/double value given the bits
- template<size_t _Size>
- IEEE754 ( bitset<_Size> bits )
- {
- numBits = bits.to_ullong ( );
- b_ToBits = false;
- if ( _Size == 32 )
- {
- EXPLENGTH = 8;
- BITSIZE = 32;
- unsigned temp = (unsigned) numBits; // Convert to a 32 bit datatype
- float fTrueNum;
- memcpy ( &fTrueNum, &temp, sizeof fTrueNum ); // Read true value from memory
- trueNum = fTrueNum;
- }
- else
- {
- EXPLENGTH = 11;
- BITSIZE = 64;
- memcpy ( &trueNum, &numBits, sizeof trueNum ); // Read true value from memory
- }
- for ( int i = 0; i < BITSIZE / 2; i++ ) // Reversing the array
- if ( bits[ i ] != bits[ BITSIZE - 1 - i ] )
- bits = bits.flip ( i ).flip ( BITSIZE - 1 - i );
- num = ( numBits != 0 ); // 0 if all bits are 0
- int exp = 0;
- for ( int i = 1; i <= EXPLENGTH; i++ ) // Calculating the exponent
- exp |= ( (int) ( bits[ i ] ) << ( EXPLENGTH - i ) );
- for ( int i = EXPLENGTH + 1; i < BITSIZE; i++ ) // Iterate over mantissa bits
- if ( bits[ i ] )
- num += pow ( 2, ( EXPLENGTH - i ) ); // Binary to fraction
- exp -= ( 1UL << ( EXPLENGTH - 1 ) ) - 1; // Subtracting the bias
- num *= pow ( 2, exp ); // Multiply by the exponent
- if ( bits[ 0 ] ) // Sign bit
- num *= -1;
- float fTrueNum = (float) trueNum;
- if ( BITSIZE == 32 )
- b_Success = fTrueNum == (float) num; // Convert to 32 bit and compare
- else
- b_Success = trueNum == num;
- }
- // Calculate the bits for representing a float/double
- void getBits ( )
- {
- numBits = 0;
- if ( num == 0 )
- return;
- else if ( num < 0 )
- numBits = 1ULL << ( BITSIZE - 1 ); // Set sign bit if negative
- bit64 exp = ( 1ULL << ( EXPLENGTH - 1 ) ) - 1; // Bias = 2 ^ ( EXPLENGTH - 1 ) - 1
- double backup = abs ( num );
- while ( backup >= 1 ) // Reduce a big number to a fraction
- {
- exp++;
- backup /= 2;
- }
- while ( backup < 0.5 ) // In case the number is 'too small'
- {
- exp--;
- backup *= 2;
- }
- bit64 mantissa = GetMantissa ( ToBits ( backup ), &exp );
- // MANTISSALENGTH = ( BITSIZE - EXPLENGTH - 1 )
- numBits = numBits | ( exp << ( BITSIZE - EXPLENGTH - 1 ) ) | ( mantissa >> ( EXPLENGTH + 1 ) );
- // sign bit | exponent bits left shifted by 23/52 | mantissa bits right shifted
- }
- // Get the binary representation of a fraction
- bit64 ToBits ( double n ) // Fractional part to Binary
- {
- bit64 bits = 0;
- for ( int i = ( BITSIZE - 1 ); i != 0; i-- ) // Calculate only till BITSIZE bits
- {
- n *= 2;
- if ( floor ( n ) == 1 ) // n >= 1
- bits |= 1ULL << i; // 2 ^ i
- n -= floor ( n );
- }
- return bits;
- }
- // Calculate the bits for mantissa given the
- // bits for fractional part and exponent
- bit64 GetMantissa ( bit64 frac, bit64 *exp )
- {
- while ( !( frac & ( 1ULL << ( BITSIZE - 1 ) ) ) ) // MSB not set
- {
- frac <<= 1; // Left Shift
- ( *exp )--; // Decrement exponent
- }
- ( *exp )--; // Put the first set bit to the left of point
- frac <<= 1; // Lose the first set bit
- return frac & ( ~( (bit64) ( BITSIZE == 32 ) << ( BITSIZE ) ) );
- /*Fix for float, as the MSB doesn't fall off on left shift*/
- }
- // Print the bits with proper spaces
- template<size_t _Size>
- void PrintBits ( bitset <_Size> bits )
- {
- cout << bits[ _Size - 1 ] << " ";
- for ( int i = 1; i <= EXPLENGTH; i++ )
- cout << bits[ _Size - i - 1 ];
- cout << " ";
- for ( int i = EXPLENGTH + 1; i < BITSIZE; i++ )
- cout << bits[ _Size - i - 1 ];
- cout << endl;
- }
- // Display the converted result
- bool Show ( )
- {
- if ( b_ToBits )
- {
- cout << BITSIZE << " Bits:\t";
- if ( BITSIZE == 64 )
- PrintBits ( bitset<64> ( numBits ) );
- else
- PrintBits ( bitset<32> ( numBits ) );
- }
- else
- {
- if ( BITSIZE == 64 )
- cout << "Double:\t" << num << endl;
- else
- cout << "Float:\t" << (float) num << endl;
- }
- return b_Success;
- }
- };
- int main ( ) // Driver
- {
- IEEE754 *converter;
- while ( true )
- {
- cout << "1:\tFloat to IEEE754\n2:\tIEEE754 to Float\n0:\tEXIT\nChoice:\t";
- int choice, size;
- cin >> choice;
- if ( !choice )
- break;
- cout << "1:\t32 Bit\n2:\t64 Bit\nChoice:\t";
- cin >> size;
- switch ( choice )
- {
- case 1:
- cout << "Enter the number:\t";
- double num;
- cin >> num;
- if ( size == 1 )
- converter = new IEEE754 ( (float) num );
- else
- converter = new IEEE754 ( num );
- break;
- default:
- case 2:
- cout << "Enter the bits:\t";
- if ( size == 1 )
- {
- bitset<32> bits;
- cin >> bits;
- converter = new IEEE754 ( bits );
- }
- else
- {
- bitset<64> bits;
- cin >> bits;
- converter = new IEEE754 ( bits );
- }
- break;
- }
- cout << ( converter->Show ( ) ? "" : "Conversion Unsuccessful!" ) << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement