explanation for this output

D

deepak

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?
 
D

David Tiktin

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
 
W

Walter Roberson

How the following code is working.
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.
 
W

Walter Roberson

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.
 
U

user923005

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
*/
 
A

Army1987

user923005 said:
/* 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.
 
M

Martin Ambuhl

deepak said:
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.h> and 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.
 
S

Sjouke Burry

deepak said:
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;
 
U

user923005

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.
 
R

Richard Heathfield

user923005 said:

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."
 
B

Barry Schwarz

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
 
D

deepak

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 -
 
C

CBFalconer

deepak said:
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.
 
C

CBFalconer

Barry said:
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.
 
K

Keith Thompson

CBFalconer said:
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.
 
C

CBFalconer

Keith said:
.... 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.
 
D

deepak

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?
 
B

Barry Schwarz

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.


Remove del for email
 
K

Keith Thompson

deepak said:
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.
 
A

Army1987

user923005 said:
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.
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top