int64 from int 32

P

Peerless

Hi,
For some reason the below code doesnt produce results as i expect.

#include<stdio.h>

int main()
{

int hi=0xff;
int low=0xee;
long long big ;
big = ((long long) hi ) << 32 | low;

printf("%16x \n ",big);

}

I am lost trying to figure out the mistake i am making.Can you help me
out.Is it compiler dependent?

Deepak
 
N

Nate Eldredge

Peerless said:
Hi,
For some reason the below code doesnt produce results as i expect.

#include<stdio.h>

int main()
{

int hi=0xff;
int low=0xee;
long long big ;
big = ((long long) hi ) << 32 | low;

printf("%16x \n ",big);

}

I am lost trying to figure out the mistake i am making.Can you help me
out.Is it compiler dependent?

The %x specifier for printf expects an unsigned argument, not a long
long. Using %llx will use an unsigned long long. So you might want

unsigned long long big;
big = ((unsigned long long)hi) << 32 | low;
printf("%16llx\n", big);

This conforms to the C99 standard, by the way, so it shouldn't be
compiler dependent.
 
J

jameskuyper

Peerless said:
Hi,
For some reason the below code doesnt produce results as i expect.

#include<stdio.h>

int main()
{

int hi=0xff;
int low=0xee;
long long big ;
big = ((long long) hi ) << 32 | low;

printf("%16x \n ",big);

}

I am lost trying to figure out the mistake i am making.Can you help me
out.Is it compiler dependent?

Support for 'long long' is compiler dependent, because not all
compilers conform to the C99 standard in that regard yet. However, if
that had been your problem, your code would never have compiled.

I strongly recommend using unsigned types whenever you are performing
shifts or bit-masking operations. However, for the particular values
involved in your program, that's not a problem.

What is a problem is that 'big' is a "long long", and you're using
%16x as your format code, which requires an "unsigned int" argument.
After changing everything to an unsigned type, you should use
"%16llx", which expects an "unsigned long long" argument.
 
K

Keith Thompson

Peerless said:
For some reason the below code doesnt produce results as i expect.

#include<stdio.h>

int main()
{

int hi=0xff;
int low=0xee;
long long big ;
big = ((long long) hi ) << 32 | low;

printf("%16x \n ",big);

}

I am lost trying to figure out the mistake i am making.Can you help me
out.Is it compiler dependent?

"%16x" expects an argument of type unsigned int. You're giving it an
argument of type long long. Use "%16llx". (It's not certain that
your runtime library will support this.)

Actually, I'd probably use "%016llx" to get the leading zeros.

Also, why do you have spaces before and after the "\n"?
 
K

Keith Thompson

Nate Eldredge said:
The %x specifier for printf expects an unsigned argument, not a long
long. Using %llx will use an unsigned long long. So you might want

unsigned long long big;
big = ((unsigned long long)hi) << 32 | low;
printf("%16llx\n", big);

This conforms to the C99 standard, by the way, so it shouldn't be
compiler dependent.

Um, are you suggesting that all compilers conform to the C99 standard?

Quibble: It's the runtime library, not the compiler, that implements
printf and the "%llx" format. Both the library and the compiler are
part of the implementation.
 
P

Peter Nilsson

Keith Thompson said:
Um, are you suggesting that all compilers conform to
the C99 standard?

Quibble: It's the runtime library, not the compiler,
that implements printf and the "%llx" format.  Both
the library and the compiler are part of the
implementation.

Do you know of any packaged C90 implementations that
support long long but don't support ll? It's been a
well over a decade since I've seen a C90 implementation
use L as the length specifier for long long.
 
K

Keith Thompson

Peter Nilsson said:
Do you know of any packaged C90 implementations that
support long long but don't support ll? It's been a
well over a decade since I've seen a C90 implementation
use L as the length specifier for long long.

Packaged? No. But gcc, for example, is just a compiler; it isn't
bundled with a runtime library. It uses whatever C runtime library is
available on the platform. *If* there are still runtime libraries
that doesn't support "%llx" (perhaps because the don't support long
long at all), and if gcc is available on such sytems, then there are C
implementations that support long long but not "%llx".

I'm sure there have been such systems in the past. I couldn't tell
you which systems they are, and I don't know whether they're still in
sufficiently widespread use to be a significant concern.

gcc may not be the only example of this.

Bottom line: Check this before depending on it.
 
J

jacob navia

Peerless said:
Hi,
For some reason the below code doesnt produce results as i expect.

#include<stdio.h>

int main()
{

int hi=0xff;
int low=0xee;
long long big ;
big = ((long long) hi ) << 32 | low;

printf("%16x \n ",big);

}

I am lost trying to figure out the mistake i am making.Can you help me
out.Is it compiler dependent?

Deepak

Using the lcc-win compiler I obtain:
d:\lcc\mc74\test>lc tll.c
Warning tll.c: 11 printf argument mismatch for format x. Expected int
got long long
0 errors, 1 warning

It helps to get a compiler with good warnings.
 
M

Martien Verbruggen

Using the lcc-win compiler I obtain:
d:\lcc\mc74\test>lc tll.c
Warning tll.c: 11 printf argument mismatch for format x. Expected int
got long long

Isn't the compiler supposed to expect an unsigned int here, instead of
an int?
0 errors, 1 warning

It helps to get a compiler with good warnings.

FWIW, gcc also warns for this, but it claims to be expecting an
unsigned int.

Martien
 
K

Keith Thompson

Martien Verbruggen said:
Peerless wrote: [...]
long long big ; [...]
printf("%16x \n ",big);
[...]

Using the lcc-win compiler I obtain:
d:\lcc\mc74\test>lc tll.c
Warning tll.c: 11 printf argument mismatch for format x. Expected int
got long long

Isn't the compiler supposed to expect an unsigned int here, instead of
an int?

Yes. More precisely, printf expects an unsigned int; the compiler
isn't required to warn you about it, but it chooses to do so. (To be
clear, that's a good thing.)

Out of curiosity, what does lcc-win do with this?

#include <stdio.h>
int main(void)
{
int i = 0;
unsigned int ui = 0;
long l = 0;
unsigned long ul = 0;
printf("i = %x\n", i);
printf("ui = %x\n", ui); /* ok */
printf("l = %x\n", l);
printf("ul = %x\n", ul);
return 0;
}

Warnings would be appropriate for the first, third, and fourth
printfs, though it could be argued that the first is ok. The third
and fourth are certainly a problem if int and long are of different
sizes; even if they're the same size for a given implementation, IMHO
a warning is sill appropriate.
 
K

Keith Thompson

Joe Wright said:
What did you expect? Try this.

#include <stdio.h>

int main(void)
{
int hi = 0xff;
int low = 0xee;
long long big;
big = ((long long)hi) << 32 | low;
printf("%016Lx\n", big);
return 0;
}

The 'L' length modified applies to long double. The format for
unsigned long long in hex is "%llx".
 
K

Keith Thompson

Joe Wright said:
My implementation gives me a choice of L or ll.

That's a legal extension. printf("%016Lx\n", big) invokes undefined
behavior; if your implementation chooses to treat it as equivalent to
printf("%016llx\n", big), it's entitled to do so.

But unless you're stuck with non-conforming implementation that
supports "L" but not "ll", there's no reason to use "L".
 
P

Peerless

"%16x" expects an argument of type unsigned int.  You're giving it an
argument of type long long.  Use "%16llx".  (It's not certain that
your runtime library will support this.)

Actually, I'd probably use "%016llx" to get the leading zeros.

Thanks. How does the compiler implement integers which are greater
than the word length of the cpu? I am trying to understand how bit
shifts greater for long long are achieved in a 32 bit machine. Not
sure whether this is the right place to ask,if it doesnt please let me
know where I can post this question.

Deepak.P
 
P

Peerless

Keith said:
Joe Wright said:
Keith Thompson wrote:
[...]
What did you expect? Try this.
#include <stdio.h>
int main(void)
{
   int hi = 0xff;
   int low = 0xee;
   long long big;
   big = ((long long)hi) << 32 | low;
   printf("%016Lx\n", big);
   return 0;
}
The 'L' length modified applies to long double.  The format for
unsigned long long in hex is "%llx".
My implementation gives me a choice of L or ll.
That's a legal extension.  printf("%016Lx\n", big) invokes undefined
behavior; if your implementation chooses to treat it as equivalent to
printf("%016llx\n", big), it's entitled to do so.
But unless you're stuck with non-conforming implementation that
supports "L" but not "ll", there's no reason to use "L".

Agreed.
 
I

Ian Collins

Peerless said:
Thanks. How does the compiler implement integers which are greater
than the word length of the cpu? I am trying to understand how bit
shifts greater for long long are achieved in a 32 bit machine. Not
sure whether this is the right place to ask,if it doesnt please let me
know where I can post this question.
Look at the generated code, each compiler will have its own ways
depending on the platform.
 
F

Flash Gordon

Keith Thompson wrote, On 12/11/08 21:16:
Packaged? No. But gcc, for example, is just a compiler; it isn't
bundled with a runtime library. It uses whatever C runtime library is
available on the platform. *If* there are still runtime libraries
that doesn't support "%llx" (perhaps because the don't support long
long at all), and if gcc is available on such sytems, then there are C
implementations that support long long but not "%llx".

I believe that the library from MS is one such, and MinGW uses that
library. Some people consider MinGW to be a packaged solution (it comes
with more than just a compiler) even though it does not include its own
library.
I'm sure there have been such systems in the past. I couldn't tell
you which systems they are, and I don't know whether they're still in
sufficiently widespread use to be a significant concern.

MinGW, sufficiently recent ports of gcc to SCO 5.0.5 (I know of people
still using this version of SCO), I suspect there may be others. Howver,
as you say, they may not be of interest to the OP.
gcc may not be the only example of this.

Bottom line: Check this before depending on it.

Agreed.
 
J

Joachim Schmitz

Peter said:
Do you know of any packaged C90 implementations that
support long long but don't support ll? It's been a
well over a decade since I've seen a C90 implementation
use L as the length specifier for long long.

Isn't L the lenth specifier for long double?

BTW: I do know one c89 implementation that supported long long, but not
unsigned long long, bizarr, eh?

Bye, Jojo
 
J

jacob navia

Martien said:
Isn't the compiler supposed to expect an unsigned int here, instead of
an int?


FWIW, gcc also warns for this, but it claims to be expecting an
unsigned int.

Martien


True. I have fixed the warning message text. Now it will say it expects
unsigned when using formats o, u, x or X.

Thanks for your remark.
 
C

CBFalconer

Peerless said:
.... snip ...

Thanks. How does the compiler implement integers which are greater
than the word length of the cpu? I am trying to understand how bit
shifts greater for long long are achieved in a 32 bit machine. Not
sure whether this is the right place to ask,if it doesnt please
let me know where I can post this question.

The method varies. For example, the system may provide a
subroutine to perform it, and call that as needed. Or it may
generate the machine code to operate on a sequence of words.
 
K

Keith Thompson

CBFalconer said:
The method varies. For example, the system may provide a
subroutine to perform it, and call that as needed. Or it may
generate the machine code to operate on a sequence of words.

Or the CPU might provide direct support for operations on quantities
bigger than the "word" size. (This gets into questions about what a
"word" is; I don't think there's any universally accepted definition.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top