By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,852 Members | 2,152 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,852 IT Pros & Developers. It's quick & easy.

explanation for this output

P: n/a
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?

Jun 20 '07 #1
Share this Question
Share on Google+
19 Replies


P: n/a
On 20 Jun 2007, deepak <de*********@gmail.comwrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the
registers in the processor?
Here's a hint:

9961472000 = 1001010001110000000000000000000000
1371537408 = 01010001110000000000000000000000

Try it with 3200LL.

Dave

--
D.a.v.i.d T.i.k.t.i.n
t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m
Jun 20 '07 #2

P: n/a
In article <11**********************@x35g2000prf.googlegroups .com>,
deepak <de*********@gmail.comwrote:
>How the following code is working.
>main() {
int a = 38, b = 13;
unsigned long long c;
c = a * (1<<b) * 32000;
printf("%llu", c);
}
>The output of this code is not 9961472000 and it is 1371537408.
>How this converting in to this number? Is it because of the registers
in the processor?
The fact that you assign the output to a long long variable
does not mean that the expression will be evaluated in long long.
Instead, because the variables inolved are all int, the value will
be evaluated using int arithmetic, will encounter UB because of
the arithmetic overflow of int [on most systems], and whatever
comes out will be widened to the long long c.

Try

c = (long long) a * (1LL<<b) * 32000LL;

(probably there's a slightly more compact expression with the
same results, but the above doesn't require that the code
maintainers think about the arcane details of width promotions.
--
There are some ideas so wrong that only a very intelligent person
could believe in them. -- George Orwell
Jun 20 '07 #3

P: n/a
In article <Xn**********************************@216.196.97.1 36>,
David Tiktin <dt*****@nospam.totally-bogus.comwrote:
>On 20 Jun 2007, deepak <de*********@gmail.comwrote:
> int a = 38, b = 13;
> c = a * (1<<b) * 32000;
>Try it with 3200LL.
No, then a * (1<<b) would still be evaluated as int; the
unconstrained width evaluation of 38 * 2**13 is 311296
which exceeds the guaranteed width of int (which only has to
go as high as 32767). What you propose might happen to
work on that particular system, if int is at least 19 value
bits wide (plus sign information), but it would just be perpetuating
the original mistake in a harder-to-find form.
--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Jun 20 '07 #4

P: n/a
On Jun 20, 10:18 am, deepak <deepakpj...@gmail.comwrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);

}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?
/* After removing the outrageous errors: */
#include <stdio.h>
int main(void) {
const unsigned long long a = 38, b = 13;
unsigned long long c;
c = a * (1ULL<<b) * 32000ULL;
printf("%llu", c);
return 0;
}
/*
C:\tmp>t
9961472000
*/

Jun 20 '07 #5

P: n/a

"user923005" <dc*****@connx.comha scritto nel messaggio news:11**********************@p77g2000hsh.googlegr oups.com...
/* After removing the outrageous errors: */
#include <stdio.h>
int main(void) {
const unsigned long long a = 38, b = 13;
unsigned long long c;
c = a * (1ULL<<b) * 32000ULL;
printf("%llu", c);
You'd better have a newline at the end of the output.
return 0;
}
/*
C:\tmp>t
9961472000
*/

Jun 20 '07 #6

P: n/a
deepak wrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?
You had at least three different ways to get this right:

#include <stdio.h>

int main(void)
{

int a = 38, b = 13;
unsigned long long c;

printf("[Output]\n");
c = (long long unsigned) a *(1u << b) * 32000;
printf("a converted to long long unsigned, c = %llu\n", c);

c = a * (1LLu << b) * 32000;
printf("shifting a long long unsigned, c=%llu\n", c);

c = a * (1u << b) * 32000LLu;
printf("using long long unsigned 32000, c = %llu\n", c);
return 0;
}

[Output]
a converted to long long unsigned, c = 9961472000
shifting a long long unsigned, c=9961472000
using long long unsigned 32000, c = 9961472000
Note the needed <stdio.hand the needed '\n' ending the last line of
output.

Your combination of implied int for the return type of main() [an error
in C99, only a bad idea in C89] and omitting returning a value from
main() [an error in C89, only a bad idea in C99] makes your program
erroneous under either standard. Please turn on your diagnostics.

Jun 20 '07 #7

P: n/a
deepak wrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?
It would help if you cast the components
to long long, because if you dont it will
execute in int, and then be converted to the
type of c.
So : c= (long long)a * ((long long)1<<b) * (long long)32000;
or : c= (long long)a * (1ll<<b) * 32000ll;
Jun 20 '07 #8

P: n/a
On Jun 20, 12:28 pm, "Army1987" <please....@for.itwrote:
"user923005" <dcor...@connx.comha scritto nel messaggionews:11**********************@p77g2000hsh .googlegroups.com.../* After removing the outrageous errors: */
#include <stdio.h>
int main(void) {
const unsigned long long a = 38, b = 13;
unsigned long long c;
c = a * (1ULL<<b) * 32000ULL;
printf("%llu", c);

You'd better have a newline at the end of the output.
Why?

Consider:
"7.19.5 File access functions
7.19.5.1 The fclose function
Synopsis
1 #include <stdio.h>
int fclose(FILE *stream);
Description
2 A successful call to the fclose function causes the stream pointed
to by stream to be
flushed and the associated file to be closed. Any unwritten buffered
data for the stream
are delivered to the host environment to be written to the file; any
unread buffered data
are discarded. Whether or not the call succeeds, the stream is
disassociated from the file
and any buffer set by the setbuf or setvbuf function is disassociated
from the stream
(and deallocated if it was automatically allocated).
Returns
3 The fclose function returns zero if the stream was successfully
closed, or EOF if any
errors were detected."

"5.1.2.2.3 Program termination
1 If the return type of the main function is a type compatible with
int, a return from the
initial call to the main function is equivalent to calling the exit
function with the value
returned by the main function as its argument;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible"

"7.20.4.3 The exit function
Synopsis
1 #include <stdlib.h>
void exit(int status);
Description
2 The exit function causes normal program termination to occur. If
more than one call to
the exit function is executed by a program, the behavior is undefined.
314 Library §7.20.4.3
©ISO/IEC ISO/IEC 9899:1999 (E)
3 First, all functions registered by the atexit function are called,
in the reverse order of
their registration,253) except that a function is called after any
previously registered
functions that had already been called at the time it was registered.
If, during the call to
any such function, a call to the longjmp function is made that would
terminate the call
to the registered function, the behavior is undefined.
4 Next, all open streams with unwritten buffered data are flushed, all
open streams are
closed, and all files created by the tmpfile function are removed.
5 Finally, control is returned to the host environment. If the value
of status is zero or
EXIT_SUCCESS, an implementation-defined form of the status successful
termination is
returned. If the value of status is EXIT_FAILURE, an implementation-
defined form
of the status unsuccessful termination is returned. Otherwise the
status returned is
implementation-defined.
Returns
6 The exit function cannot return to its caller.
7.20.4.4 The _Exit function
Synopsis
1 #include <stdlib.h>
void _Exit(int status);
Description
2 The _Exit function causes normal program termination to occur and
control to be
returned to the host environment. No functions registered by the
atexit function or
signal handlers registered by the signal function are called. The
status returned to the
host environment is determined in the same way as for the exit
function (7.20.4.3).
Whether open streams with unwritten buffered data are flushed, open
streams are closed,
or temporary files are removed is implementation-defined.
Returns
3 The _Exit function cannot return to its caller.
253) Each function is called as many times as it was registered, and
in the correct order with respect to
other registered functions."

I think it's pretty plain.

return 0;
}
/*
C:\tmp>t
9961472000
*/- Hide quoted text -

- Show quoted text -

Jun 20 '07 #9

P: n/a
user923005 said:
On Jun 20, 12:28 pm, "Army1987" <please....@for.itwrote:
>"user923005" <dcor...@connx.comha scritto nel
messaggionews:11**********************@p77g2000hsh .googlegroups.com...>
>/* After removing the outrageous errors: */
#include <stdio.h>
int main(void) {
const unsigned long long a = 38, b = 13;
unsigned long long c;
c = a * (1ULL<<b) * 32000ULL;
printf("%llu", c);

You'd better have a newline at the end of the output.

Why?
Good programming practice. If the output is redirected into a file, that
file can subsequently be used as valid text input into a C program,
eliminating one point of reliance on implementation-defined behaviour.

4.9.2: "A text stream is an ordered sequence of characters composed into
lines, each line consisting of zero or more characters plus a
terminating new-line character. Whether the last line requires a
terminating new-line character is implementation-defined."

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 20 '07 #10

P: n/a
On Thu, 21 Jun 2007 00:20:25 +0200, Sjouke Burry
<bu*************@ppllaanneett.nnlllwrote:
>deepak wrote:
>How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?
It would help if you cast the components
to long long, because if you dont it will
execute in int, and then be converted to the
type of c.
So : c= (long long)a * ((long long)1<<b) * (long long)32000;
or : c= (long long)a * (1ll<<b) * 32000ll;
The expression (1ll<<b) is sufficient to cause all the arithmetic to
be performed as long long.
Remove del for email
Jun 21 '07 #11

P: n/a
On Jun 20, 10:26 pm, David Tiktin <dtik...@nospam.totally-bogus.com>
wrote:
On 20 Jun 2007, deepak <deepakpj...@gmail.comwrote:


How the following code is working.
main() {
int a = 38, b = 13;
unsigned long long c;
c = a * (1<<b) * 32000;
printf("%llu", c);
}
The output of this code is not 9961472000 and it is 1371537408.
How this converting in to this number? Is it because of the
registers in the processor?

Here's a hint:

9961472000 = 1001010001110000000000000000000000
1371537408 = 01010001110000000000000000000000
I know this. but want to know how it is happening.
>
Try it with 3200LL.

Dave

--
D.a.v.i.d T.i.k.t.i.n
t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m- Hide quoted text -

- Show quoted text -

Jun 21 '07 #12

P: n/a
deepak wrote:
>
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;
c = a * (1<<b) * 32000;
printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the
registers in the processor?
It overflowed, and behaviour is either system dependent or
undefined. It's in the standard.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 21 '07 #13

P: n/a
Barry Schwarz wrote:
<bu*************@ppllaanneett.nnlllwrote:
deepak wrote:
>>How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;
printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the
registers in the processor?

It would help if you cast the components to long long, because
if you dont it will execute in int, and then be converted to the
type of c.
So : c= (long long)a * ((long long)1<<b) * (long long)32000;
or : c= (long long)a * (1ll<<b) * 32000ll;

The expression (1ll<<b) is sufficient to cause all the arithmetic
to be performed as long long.
No it isn't. It is sufficient to cause overflows on most machines.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com

Jun 21 '07 #14

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Barry Schwarz wrote:
><bu*************@ppllaanneett.nnlllwrote:
>deepak wrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;
printf("%llu", c);
}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the
registers in the processor?

It would help if you cast the components to long long, because
if you dont it will execute in int, and then be converted to the
type of c.
So : c= (long long)a * ((long long)1<<b) * (long long)32000;
or : c= (long long)a * (1ll<<b) * 32000ll;

The expression (1ll<<b) is sufficient to cause all the arithmetic
to be performed as long long.

No it isn't. It is sufficient to cause overflows on most machines.
How so? (Note that it's 1ll, equivalent to 1LL, not 111.)

1ll is of type long long, so 1ll<<b is of type long long; the type
propagates to the rest of the expression, and both multiplications are
performed in type long long.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 21 '07 #15

P: n/a
On Jun 20, 10:18 pm, deepak <deepakpj...@gmail.comwrote:
How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;
Is it because the processor will store the value in a temperory
register
with the size of int and this creates overflow.
This assumption is correct?
>
printf("%llu", c);

}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?

Jun 21 '07 #16

P: n/a
On Wed, 20 Jun 2007 23:25:52 -0700, deepak <de*********@gmail.com>
wrote:
>On Jun 20, 10:18 pm, deepak <deepakpj...@gmail.comwrote:
>How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

Is it because the processor will store the value in a temperory
register
with the size of int and this creates overflow.
This assumption is correct?
The code generated may or may not create temporary values. Those
values, if they exist, may or may not be stored in a register. These
are implementation details which are normally not addressed in this
newsgroup.

Every term on the right is an int. Therefore, all the computations
will be done as int. For any system with int 32 bits wide or less,
the computed value exceeds INT_MAX. The value is not converted to
long long until after all the computations are performed. Therefore
the wrong value is being converted.
>
>>
printf("%llu", c);

}

The output of this code is not 9961472000 and it is 1371537408.

How this converting in to this number? Is it because of the registers
in the processor?

Remove del for email
Jun 21 '07 #17

P: n/a
deepak <de*********@gmail.comwrites:
On Jun 20, 10:18 pm, deepak <deepakpj...@gmail.comwrote:
>How the following code is working.

main() {

int a = 38, b = 13;
unsigned long long c;

c = a * (1<<b) * 32000;

Is it because the processor will store the value in a temperory
register with the size of int and this creates overflow.
It has nothing to do with temporary registers (though the generated
code may well use temporary registers). It's just a matter of how the
C standard specifies that the expression is evaluated.

In almost all cases, the type of an expression is determined entirely
by the expression itself, not by the context in which it appears.
Everything in "a * (1<<b) * 32000" is of type int, so everything is
evaluated in type int, leading to a possible overflow. This overflow
occurs *before* you assign the result to an unsigned long long object.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 21 '07 #18

P: n/a
"user923005" <dc*****@connx.comha scritto nel messaggio news:11**********************@g4g2000hsf.googlegro ups.com...
>On Jun 20, 12:28 pm, "Army1987" <please....@for.itwrote:
>"user923005" <dcor...@connx.comha scritto nel messaggionews:11**********************@p77g2000hsh .googlegroups.com.../*
After removing the outrageous errors: */
#include <stdio.h>
int main(void) {
const unsigned long long a = 38, b = 13;
unsigned long long c;
c = a * (1ULL<<b) * 32000ULL;
printf("%llu", c);

You'd better have a newline at the end of the output.

Why?

Consider:
"7.19.5 File access functions
7.19.5.1 The fclose function
Synopsis
1 #include <stdio.h>
int fclose(FILE *stream);
Description
2 A successful call to the fclose function causes the stream pointed
to by stream to be
flushed and the associated file to be closed. Any unwritten buffered
data for the stream
are delivered to the host environment to be written to the file; any
unread buffered data
are discarded. Whether or not the call succeeds, the stream is
disassociated from the file
and any buffer set by the setbuf or setvbuf function is disassociated
from the stream
(and deallocated if it was automatically allocated).
Returns
3 The fclose function returns zero if the stream was successfully
closed, or EOF if any
errors were detected."

"5.1.2.2.3 Program termination
1 If the return type of the main function is a type compatible with
int, a return from the
initial call to the main function is equivalent to calling the exit
function with the value
returned by the main function as its argument;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible"

"7.20.4.3 The exit function
Synopsis
1 #include <stdlib.h>
void exit(int status);
Description
2 The exit function causes normal program termination to occur. If
more than one call to
the exit function is executed by a program, the behavior is undefined.
314 Library §7.20.4.3
©ISO/IEC ISO/IEC 9899:1999 (E)
3 First, all functions registered by the atexit function are called,
in the reverse order of
their registration,253) except that a function is called after any
previously registered
functions that had already been called at the time it was registered.
If, during the call to
any such function, a call to the longjmp function is made that would
terminate the call
to the registered function, the behavior is undefined.
4 Next, all open streams with unwritten buffered data are flushed, all
open streams are
closed, and all files created by the tmpfile function are removed.
5 Finally, control is returned to the host environment. If the value
of status is zero or
EXIT_SUCCESS, an implementation-defined form of the status successful
termination is
returned. If the value of status is EXIT_FAILURE, an implementation-
defined form
of the status unsuccessful termination is returned. Otherwise the
status returned is
implementation-defined.
Returns
6 The exit function cannot return to its caller.
7.20.4.4 The _Exit function
Synopsis
1 #include <stdlib.h>
void _Exit(int status);
Description
2 The _Exit function causes normal program termination to occur and
control to be
returned to the host environment. No functions registered by the
atexit function or
signal handlers registered by the signal function are called. The
status returned to the
host environment is determined in the same way as for the exit
function (7.20.4.3).
Whether open streams with unwritten buffered data are flushed, open
streams are closed,
or temporary files are removed is implementation-defined.
Returns
3 The _Exit function cannot return to its caller.
253) Each function is called as many times as it was registered, and
in the correct order with respect to
other registered functions."

I think it's pretty plain.
Where on Earth does it say that return 0; will automatically add a
newline to stdout for you?

7.19.2 p2:
A text stream is an ordered sequence of characters composed into lines, each line

consisting of zero or more characters plus a terminating new-line character. Whether the

last line requires a terminating new-line character is implementation-defined.

If you ran that program on one of the Unix-like systems I've used,
you would get the prompt on the same line of the output, which does
not look very good.
return 0;
}
/*
C:\tmp>t
9961472000
*/- Hide quoted text -

- Show quoted text -


Jun 21 '07 #19

P: n/a
Keith Thompson wrote:
>
.... snip ...
>
How so? (Note that it's 1ll, equivalent to 1LL, not 111.)

1ll is of type long long, so 1ll<<b is of type long long; the type
propagates to the rest of the expression, and both multiplications
are performed in type long long.
Ulp. Why to write 1LL. Looks just like 111 here.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 21 '07 #20

This discussion thread is closed

Replies have been disabled for this discussion.