Algo sobre el binario C++ [cerrado]

#include <iostream>

using namespace std;

int main()
{
    for(int i=63;i>=0;--i)
    {
        cout<<(((1<<63)+1)&(/*(long long)*/1<<i)?"1":"0");
    }

    return 0;
}

Here is the result:0000000000000000000000000000000100000000000000000000000000000001

Well, who can tell me how does the result come?

I ask this question just because I am reading the "CA-2002-25" about the bug of XDR. And I want to now more about overflow in C Plus Plus.

preguntado el 31 de julio de 12 a las 15:07

Could it be that the literal is unsigned, and the two-step numeric cast (sign change, size change) screws stuff up somewhere? -

I habitually refuse to read code that doesn't comment on what it's Supuesto to be doing. Doubly so on code that doesn't have spaces. -

Aside from the evil bit that's your loop body, shouldn't that be 0x7fffffff00000000ll (i.e., a long long literal) instead of (long long)0x7fffffff00000000 (i.e., a potentially overflowing int literal casted to long long)? -

Your loop doesn't even tocar num, what are you expecting? Additionally, my compiler is giving some helpful warnings. -

Man you down voters are abusive. If you don't want or can't understand the question move on or add a simple comment. to me the question is quite clear The site is getting flooded by a lot of self righteous people that would rather be mean and abusive rather than helpful (a -1 should have been more than enough to get the guy to clean up his question). Give the guy a break and just answer the question. -

2 Respuestas

Well, it is pretty hard to tell what you were actually expecting, but running it through the compiler generates lots of useful warnings. If you add long long integral literal sigils all over the place, like so:

#include <iostream>

using namespace std;

int main()
{
    long long num = 0x7fffffff00000000ULL >> 32;
    for(int i=63;i>=0;--i)
    {
        cout<<(((1ULL<<63)+1ULL)&(1ULL<<i)?"1":"0");
    }

    return 0;
}

You get the answer

1000000000000000000000000000000000000000000000000000000000000001

which is what I would expect your loop to do. I have no idea what you expected num to do, as you didn't use the value, but hey! I decorated that too.

Eso responde tu pregunta?

Respondido 31 Jul 12, 16:07

1LL << 63 feels like undefined behaviour due to signed integer overflow... - Kerrek SB

@KerrekSB: It works the same way as unsigned long x = -1; The problem occurs when you flow all the bits passed the end (ie << 64) then it is undefined. - martín york

@KerrekSB: That's a reasonable point. I've updated the code listing to reflect that. I'm often a bit lazy about specifying unsignedness when working with integer literals in this fashion as it doesn't usually cause any issues. - Rook

@LokiAstari: Converting a signed to an unsigned integer is well defined. Overflowing a signed integer, however, is not, as far as I know. - Kerrek SB

prueba esto:

#include <iostream>

int main()
{
    long long num=0x7fffffff00000000ll >> 32; 
                                //  ^^    
                                // Literals are by default int
                                // need to add ll to let the compiler
                                // know it is long long
    for(int i=63; i>=0 ;--i)
    {   
        long long mask = (1ll << i); 
                       //  ^^    Note here I want this to be a long long
                       //        before I start shifting it.
        std::cout << ((num & mask)?1:0);
    }   
    std::cout << "\n";

    return 0;
}

./a.out
0000000000000000000000000000000001111111111111111111111111111111

Mirando tu código:

cout<<(((1<<63)+1)&(/*(long long)*/1<<i)?"1":"0");

There is a constant in there:

int val = (1<<63)+1;
// since these are all integer literals (and I am guessing your platform is 32 bit)
0x00000001  or 000000000000000000000000000000001

Thus when you loop over it with the second part of that expression:

/*(long long)*/1<<i

After i > 32 the results are undefined but it looks like it is wrapping the bit around and starting again. So you are setting

10000000000000000000000000000000100000000000000000000000000000001
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    Mask bit wrapped around
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The mask on 0x00000001

Respondido 31 Jul 12, 17:07

thx, but it's not what I want. I know the correct method, and what I really want is how does the result come and what happend when the "mask" overflow? - códigodom

@CodeSun: Which you posible did not state in your question. That's why it accumulated so many downvotes: Even after you added a hint that you are looking at a particular bug and want to know about "overflow", your question is still listed as "Something about C++ binary", and that you want to know why the commenting out of the (long long) cast changes the result. To que, you would probably have gotten a simple, one-line answer. - DevSolar

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.