Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > explanation for this output

Reply
Thread Tools

explanation for this output

 
 
deepak
Guest
Posts: n/a
 
      06-20-2007
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?

 
Reply With Quote
 
 
 
 
David Tiktin
Guest
Posts: n/a
 
      06-20-2007
On 20 Jun 2007, deepak <(E-Mail Removed)> 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?


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
 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      06-20-2007
In article <(E-Mail Removed) .com>,
deepak <(E-Mail Removed)> 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?


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
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      06-20-2007
In article <Xns99556A2F5460Fdtiktinnospambogusco@216.196.97.1 36>,
David Tiktin <(E-Mail Removed)-bogus.com> wrote:
>On 20 Jun 2007, deepak <(E-Mail Removed)> wrote:


>> 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
 
Reply With Quote
 
user923005
Guest
Posts: n/a
 
      06-20-2007
On Jun 20, 10:18 am, deepak <(E-Mail Removed)> 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?


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

 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      06-20-2007

"user923005" <(E-Mail Removed)> ha scritto nel messaggio news:(E-Mail Removed) 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
> */
>



 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      06-20-2007
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.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.

 
Reply With Quote
 
Sjouke Burry
Guest
Posts: n/a
 
      06-20-2007
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;
 
Reply With Quote
 
user923005
Guest
Posts: n/a
 
      06-20-2007
On Jun 20, 12:28 pm, "Army1987" <(E-Mail Removed)> wrote:
> "user923005" <(E-Mail Removed)> ha scritto nel messaggionews:1182364457.789676.147790@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 -



 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      06-20-2007
user923005 said:

> On Jun 20, 12:28 pm, "Army1987" <(E-Mail Removed)> wrote:
>> "user923005" <(E-Mail Removed)> ha scritto nel
>>

messaggionews:1182364457.789676.147790@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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple Explanation to Networking Wirelessly?? Jaxim Wireless Networking 4 08-19-2005 05:04 AM
explanation Mariusz VHDL 1 01-13-2004 02:10 AM
DVMRP Explanation Acer0001 Cisco 0 11-20-2003 04:41 AM
Need Explanation Kaladhaur Palaniappa Perl 0 08-07-2003 09:47 AM
tracing output explanation Benjie Fallar ASP .Net 0 07-15-2003 01:34 AM



Advertisments