2

I'm working with IEEE-754 doubles, and I'd like to verify that the bit patterns match between different platforms. For this reason I would like to see the bit pattern of a double in the Visual Studio C++ Debugger.

I've tried format specifiers, but they don't seem to allow me to format a double as anything which would allow me to see the bit pattern.

One way I finally found was to use Memory View and enter the address of the variable (&x) in the address field. This allows me to set for instance 8-bit integer hex display, which gives me what I need. But is there any other more convenient way of formatting a double this way in the debugger?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Alexander Torstling
  • 18,552
  • 7
  • 62
  • 74
  • I think you could create [a nativs file](https://learn.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2019) with the the settings of bit pattern and please refer to [this](https://stackoverflow.com/questions/41221735/debugger-how-to-only-see-values-not-memory-addresses-of-variables). – Mr Qian Jan 22 '21 at 09:48
  • @PerryQian-MSFT a natvis file helps when you're working with a custom type, like a class wrapping a double, or a union of a `double` and a `long long`. But I don't think it's possible to change the format of a standard type, and even if it's possible then it's not a good idea since all variables of that type will be affected – phuclv Jan 25 '21 at 02:29

1 Answers1

4

To view the exact binary floating-point value you should print the it as hexadecimal with %a/%A or std::hexfloat instead of examining its bit pattern

printf("Hexadecimal: %a %A\n", 1.5, 1.5);
std::out << std::hexfloat << 1.5 << '\n';

However if you really need to view the actual bit pattern then you just need to reinterpret the type of the underlying memory region like auto bits = reinterpret_cast<uint64_t*>(doubleValue). You don't need to open the Memory View to achieve this, a simple cast would work in the Watch window. So to get the bit pattern of double and float use *(__int64*)&doubleValue,x and *(int*)&floatValue,x respectively. Strict aliasing does occur but you don't actually need to care about it in MSVC debugger
Note that __int64 is a built-in type of MSVC so you might want to use long long instead. Typedefs and macros like uint64_t won't work while watching

Alternatively you can access the bytes separately by casting to char* and print as an array with (char*)&doubleValue, 8, (char*)&floatValue, 4 or (char*)&floatingPoint, [sizeof floatingPoint]. This time strict aliasing doesn't occur but the output may be less readable

Demo

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • 1
    Thank you, this is exactly what I wanted! I had missed that you could cast values directly in the watch window. Another example is `*(uint64_t*)&x,bb`, which gives bit view. – Alexander Torstling Jan 25 '21 at 13:51