// // Apr. 8, 1999 // Dr. Ken Vollmar KenVollmar@mail.smsu.edu (417)836-5789 // Dept. of Computer Science www.cs.smsu.edu/~vollmar // Southwest Missouri State University // 901 S. National Ave. // Springfield, MO 65804 // // Problem: Show the hexadecimal representation of an IEEE 754 32-bit // floating point number. // It is not possible to examine the bits of a floating point data type, // nor to print the value of a f.p. type in hex. Also, if the f.p. value is // assigned to an integer type, then the bits are rearranged so that the // numeric represented value is maintained. // // Solution: Define storage space such that the same space is used for both // the f.p. data type and the integer type. Initialize the f.p. form of the // storage location, but operate on the integer form of the location. // Look at the integer form four bits at a time in a loop. At each group // of four bits, print the corresponding hexadecimal digit. #include #include #include main() { // "union" declares the members to be stored in the same memory space. union { unsigned long l; float f; } input, temporary; int denominator = 2; unsigned long mask = 0x400000; // Set to MSBit of significand unsigned long significand; long exponent; // exponent is signed (may be neg.) unsigned long sign; char dummy; // Verify that union contains equal-sized data items. // This is critical because the two types must be // stored in the same memory location. assert (sizeof(unsigned long) == sizeof(float)); cout << endl << "Default precision value for cout stmts is "; cout << cout.precision() << endl << endl; cout << endl << "Input a float value? "; cin >> input.f; cout << "\n\nThe original float value: " << input.f << endl; cout << " " << endl; cout << hex; // Format the output in hexadecimal cout << "\n\nThe hex form of original float value: " << input.l << endl; cout << " " << endl; cout << dec; // Restore data output format to decimal significand = input.l & 0x7fffff; // Isolate the significand exponent = ((input.l >> 23) & 0xff) - 127; // Isolate the exponent sign = (input.l & 0x80000000); // Isolate the sign // Show the value in the form (-1)^^s x (1 + 1/2 + ... ) x 2^^exponent. // Show only the fractions actually present in the number. cout << "Value is (-1)^^"; if (sign) cout << "1"; else cout << "0"; cout << "* ( 1 "; // Hidden bit -- always present mask = 0x400000; // Initial value of bit mask is the position of the MSBit in significand // Go through each bit of the significand, beginning at the Most Significant Bit. for (int i = 1; i <= 23; i++) // 23 bits in significand { if (significand & mask) // if the bit at the current position is a 1 { cout << " + 1/"; cout << denominator; } denominator = denominator * 2; // Update for next bit position mask >>= 1; // Mask is rotated (shifted) right by 1 position } // end for i cout << ") * 2^^(" << exponent << ")"; cout << endl << endl; mask = 0x400000; // Set to MSBit of significand significand = input.l & 0x7fffff; exponent = ((input.l >> 23) & 0xff) - 127; sign = (input.l & 0x80000000); cout << "Contribution to value, bit by bit. " << endl; cout.precision(20); // The value of temporary is initially that given by the hidden bit only // of the original input. As each bit is examined, the value of temporary // will increase based on the contribution from each bit of the significand. temporary.l = input.l & 0xff800000; // Retain only sign, exponent, and hidden bit cout << "Hidden bit: " << temporary.f << endl; for (int i = 1; i <= 23; i++) // 23 bits in significand { cout << " Bit " << i << ": "; temporary.l |= (significand & mask); // Duplicate current bit if (significand & mask) // if current bit position is set cout << temporary.f << endl; // show the cumulative value else cout << " (bit not set)" << endl; mask >>= 1; // Mask is rotated (shifted) right by 1 position } // end for i }