-1

I have to print the binary representation of a long double number for some reasons. I want to see the exact format as it remains in the computer memory.

I went through the following questions where taking a union was the the solution. For float, alternate datatype was unsigned int as both are 32-bit. For double, it was unsigned long int as both are 64-bit. But in of long double, it is 96-bit/128-bit (depending on platform) which has no similar equivalent memory consumer. So, what would be the solution?

Visited Questions:

  1. Print binary representation of a float number in C++
  2. Binary representation of a double
  3. Exact binary representation of a double
  4. How do I display the binary representation of a float or double?

ATTENTION:

It is marked as duplicate of the question How to print (using cout) the way a number is stored in memory? !

Really is it? The question mentioned question talked about integer number and accepted solution of it was bitset which just truncates the floating-point part. My main point of view is floating-point representation which has no relation with the content of that question.

Community
  • 1
  • 1
Enamul Hassan
  • 4,744
  • 22
  • 35
  • 52
  • 1
    An array of `unsigned char`, as in all other cases. – n. 'pronouns' m. Jun 16 '16 at 14:00
  • _"I want to see the exact format as it remains in the computer memory."_ Look it up on Wikipedia. – Lightness Races in Orbit Jun 16 '16 at 14:00
  • @LightnessRacesinOrbit I know how it remains dividing in mantissa and exponent. So, I want to print these 96-bit in the screen, That means how to start the coding for it. I actually looking it for some other problem, where it seemed to me, binary to decimal conversion loosing some data. Thanks – Enamul Hassan Jun 16 '16 at 14:04
  • 2
    @manetsus: Maybe you should present your [MCVE] for _that_ problem, instead of fiddling about with floating-point binary representations? – Lightness Races in Orbit Jun 16 '16 at 14:07
  • @LightnessRacesinOrbit: `cout< – Enamul Hassan Jun 16 '16 at 14:08
  • 1
    Strange! how it could be the duplicate of [C++ - How to print (using cout) the way a number is stored in memory?](http://stackoverflow.com/questions/7349689/c-how-to-print-using-cout-the-way-a-number-is-stored-in-memory) ? @Cody-gray Did you have a look on the content? – Enamul Hassan Jun 16 '16 at 14:26
  • Why, exactly, do you believe it is not a duplicate? – Cody Gray Jun 16 '16 at 14:32
  • @CodyGray: Never it could be a duplicate of that question. Because they did nothing with floating-point representation! My main concern is floating-point representation of long double. Thanks – Enamul Hassan Jun 16 '16 at 14:34
  • *"I have to print the binary representation of a long double number for some reasons. I want to see the exact format as it remains in the computer memory."* That question discusses printing (using cout) the way a number is stored in memory. Seems identical to me. It makes absolutely no difference whether it is a floating-point value or not. The procedure for printing the memory representation would be the same. – Cody Gray Jun 16 '16 at 14:36
  • Ugh, I see you aren't willing to bring any knowledge to the table. You want someone to write the code out for you. Sorry, that wasn't my intention. `std::bitset` does not have a ctor overload that takes a floating-point type. That much is obvious. You have to use standard aliasing tricks to view the memory as an array of unsigned characters. Lots of people have already pointed that out. Once you've done that, the real answer to your question is contained over there, because you want to print the binary representation. There are also other answers to that question if you don't like bitset. – Cody Gray Jun 16 '16 at 15:10
  • @manetsus: It depends on your compiler/platform. Many (mine included) make it 16 bytes to aid with alignment. Another good reason not to use some other type of some other platform-dependent size in a union. – Lightness Races in Orbit Jun 16 '16 at 16:27
  • @CodyGray You argued with me just for argument. If you answer [this question](http://stackoverflow.com/questions/7349689/c-how-to-print-using-cout-the-way-a-number-is-stored-in-memory) handling floating-point, well that is fine, but it is not obvious to answer that question. I think you know well that floating-point representation in memory is not ordinary representation like int, unsigned etc. It has issue with mantissa and exponent. You have just saw the heading and marked as duplicate. You had no idea about the intentional difference between these questions. Anyway, Thanks for reopening. – Enamul Hassan Jun 16 '16 at 17:12
  • @LightnessRacesinOrbit [This](http://stackoverflow.com/questions/37867903/does-the-implementation-of-pow-function-in-c-c-vary-with-platform-or-compile) is my original problem. Thanks. – Enamul Hassan Jun 16 '16 at 19:33
  • What do you mean I argued with you "just for argument"? Yes, certainly floating point values are represented differently in memory than integer arguments. That is of course not relevant here, since they are still represented in memory in binary format, and all you want to do is print the binary representation. I already covered this in my comment. I reopened because it wasn't worth arguing with you about it. – Cody Gray Jun 17 '16 at 05:21
  • @CodyGray Meaning of "just for argument": you have enough rep in c++ to close a question in single vote. You have seen my question and thought "Oh! Some new user posted question having no research, lets close it!" then you have close it. Later, when I shout, may be you have rethought and went to the content and understood the difference then reopened it. Now, you are giving lame excuses on your work just for claiming your wrong work as right. If you thing you are the only king here because of rep, please see the rep of accepted answerer. I would not answer you further here. That's all. :) – Enamul Hassan Jun 17 '16 at 06:59
  • I have no idea how you know so well what my thoughts and intentions were. For what it's worth, you are incorrect. I honestly felt that the answers to the other question provided the answer to your question, and that you had been provided with sufficient background knowledge to understand how to apply them and to make use of them. Clearly I was incorrect, but that doesn't mean I made the decision with any malice or superiority. Furthermore, I consider reputation to be completely meaningless. I haven't the foggiest idea what your rep is, nor do I keep up with my own. It's an imaginary number. – Cody Gray Jun 17 '16 at 07:03

1 Answers1

7

As always, the way to alias arbitrary memory is with an array of unsigned chars. Period. All those "union" solutions have undefined behaviour and are thus in fact not "solutions" whatsoever.

So copy into an unsigned char array, then just print out the byte values one by one.

Incidentally, long double is not necessarily 96-bit. It'll depend on the platform.

#include <iostream>
#include <algorithm>

int main()
{
    const long double x = 42;
    unsigned char     a[sizeof(long double)];

    std::copy(
        reinterpret_cast<const unsigned char*>(&x),
        reinterpret_cast<const unsigned char*>(&x) + sizeof(long double),
        &a[0]
    );

    std::cout << "Bytes: " << sizeof(long double) << "\nValues: ";
    std::cout << std::hex << std::showbase;
    for (auto el : a) {
        std::cout << +el << ' ';
    }

    std::cout << '\n';
}

(live demo)

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989
  • Is there any direct way to print it in binary instead of `std::hex`? Thanks – Enamul Hassan Jun 16 '16 at 14:10
  • Ow, please don't miss understand me. There is nothing wrong with your solution. But in memory, it remains binary. So, I am interested in seeing it in binary. I just asked that is there any shortcut tricks to represent it in binary as you are an expert in this field. Thanks. – Enamul Hassan Jun 16 '16 at 17:20
  • 1
    @manetsus: You mean you want to see the value of each byte in a base-2 representation? Okay so just do that then. Surely you don't need me to handhold you through every possible combination of output representation? – Lightness Races in Orbit Jun 16 '16 at 17:55
  • Yes, I meant it. Sorry, no need to do that if you are taking it as burden. You did a lot. Thanks. If you do not mind, could you please tell me what it mean by the `+` sign in `+el` in the code? – Enamul Hassan Jun 16 '16 at 18:01
  • @manetsus: Shortcut for cast to `int`. `cout`-ing a `char` does something you don't want here. – Lightness Races in Orbit Jun 16 '16 at 18:04
  • Thanks for your nice explanation. I am going to accept your answer within a short time. – Enamul Hassan Jun 16 '16 at 18:10
  • 1
    @manetsus `std::ostream` does not support binary output, you may write a function that converts `unsigned char` to binary string which is trivial. – Slava Jun 16 '16 at 18:54
  • @Slava Thanks for your attention. I have already handled it with `bitset<8>`. – Enamul Hassan Jun 16 '16 at 18:55
  • 1
    @manetsus to make it even worse - c++ does not guarantee that byte has 8 bits, but there is a very small chance you will meet a platform where it is not so. – Slava Jun 16 '16 at 18:58
  • Indeed. Do it like [this](http://stackoverflow.com/a/483653/560648) instead of `bitset<8>`. – Lightness Races in Orbit Jun 16 '16 at 19:53