Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Code problem

Reply
Thread Tools

Code problem

 
 
jacob navia
Guest
Posts: n/a
 
      12-06-2007
I posted this to comp.std.c, but may be of interest here too:

Consider this:

extern void abort(void);
int main (void)
{
unsigned long long xx;
unsigned long long *x = (unsigned long long *) &xx;

*x = -3;
*x = *x * *x;
if (*x != 9)
abort ();
return(0);
}

lcc-win interprets
*x = -3;
as
*x = 4294967293;
since x points to an UNSIGNED long long.
I cast the 32 bit integer -3 into an unsigned integer
then I cast the result to an unsigned long long.

Apparently gcc disagrees.

Am I doing something wrong somewhere?

I should first cast into a long long THEN into an unsigned
long long?

Thanks for your help.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      12-06-2007
jacob navia <> writes:

> int main (void)
> {
> unsigned long long xx;
> unsigned long long *x = (unsigned long long *) &xx;


Why the cast? It should be unnecessary.

> *x = -3;
> *x = *x * *x;
> if (*x != 9)
> abort ();
> return(0);
> }
>
> lcc-win interprets
> *x = -3;
> as
> *x = 4294967293;
> since x points to an UNSIGNED long long.


unsigned long long has to be at least 64 bits in size.
18446744073709551613 is the minimum correct value for *x here.

> I cast the 32 bit integer -3 into an unsigned integer
> then I cast the result to an unsigned long long.


I don't see any cast to unsigned int in the above program.
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      12-06-2007
jacob navia said:

> I posted this to comp.std.c, but may be of interest here too:
>
> Consider this:
>
> extern void abort(void);
> int main (void)
> {
> unsigned long long xx;
> unsigned long long *x = (unsigned long long *) &xx;


Remove the unnecessary cast:

unsigned long long *x = &xx;

>
> *x = -3;


See 6.2.5(9).

> *x = *x * *x;
> if (*x != 9)
> abort ();


It is deeply unlikely that *x will be 9 at this point.

> return(0);
> }
>
> lcc-win interprets
> *x = -3;
> as
> *x = 4294967293;
> since x points to an UNSIGNED long long.


That's a bug in lcc-win. *x must have the value ULLONG_MAX - 2, and since
ULLONG_MAX must be at least 18446744073709551615, *x must be at least
18446744073709551613.

> I cast the 32 bit integer -3 into an unsigned integer
> then I cast the result to an unsigned long long.


Why?

> Apparently gcc disagrees.
>
> Am I doing something wrong somewhere?


Yes. If your article is an accurate description of lcc-win's behaviour,
your mistake is in using a non-conforming compiler.

> I should first cast into a long long THEN into an unsigned
> long long?


No, there is almost certainly no need to cast anything at all. The first
step is to identify the problem you are trying to solve, which is far from
clear. If you want to know the result of multiplying -3 by -3, why use an
unsigned type in the first place?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
jameskuyper@verizon.net
Guest
Posts: n/a
 
      12-06-2007
jacob navia wrote:
> I posted this to comp.std.c, but may be of interest here too:
>
> Consider this:
>
> extern void abort(void);
> int main (void)
> {
> unsigned long long xx;
> unsigned long long *x = (unsigned long long *) &xx;
>
> *x = -3;
> *x = *x * *x;
> if (*x != 9)
> abort ();
> return(0);
> }
>
> lcc-win interprets
> *x = -3;
> as
> *x = 4294967293;
> since x points to an UNSIGNED long long.


The minimum value for ULLONG_MAX is 18446744073709551615, so you
should be getting a value of at least 18446744073709551613

> I cast the 32 bit integer -3 into an unsigned integer
> then I cast the result to an unsigned long long.


Why did you do that?

> Apparently gcc disagrees.
>
> Am I doing something wrong somewhere?


Yes.

> I should first cast into a long long THEN into an unsigned
> long long?


Why do you think that? Why are you using intermediaries?

You should be converting -3 directly to unsigned long long. You should
neither detour through unsigned int, nor detour through long long. The
result should be ULLONG_MAX+1-3.
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      12-06-2007
Richard Heathfield <> writes:

> jacob navia said:
>> unsigned long long xx;
>> unsigned long long *x = (unsigned long long *) &xx;
>> *x = -3;
>> *x = *x * *x;
>> if (*x != 9)
>> abort ();

>
> It is deeply unlikely that *x will be 9 at this point.


2**64 - 3 == 18446744073709551613
(18446744073709551613)**2 = 340282366920938463352694142989510901769
340282366920938463352694142989510901769 % 2**64 = 9

At least according to the calculator I have here.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-06-2007
jacob navia wrote:
> I posted this to comp.std.c, but may be of interest here too:
>
> Consider this:
>
> extern void abort(void);
> int main (void)
> {
> unsigned long long xx;
> unsigned long long *x = (unsigned long long *) &xx;


What is the cast for? (Hint: What is the type of
the expression `&xx'?)

> *x = -3;
> *x = *x * *x;
> if (*x != 9)
> abort ();
> return(0);
> }
>
> lcc-win interprets
> *x = -3;
> as
> *x = 4294967293;


That cannot possibly be correct. ULLONG_MAX is at
least 18446744073709551615, so ULLONG_MAX-2 (the required
result) is at least 18446744073709551614.

> since x points to an UNSIGNED long long.
> I cast the 32 bit integer -3 into an unsigned integer
> then I cast the result to an unsigned long long.


That would be correct iff ULLONG_MAX==ULONG_MAX.

Imagine converting a signed char to an unsigned long
by the analogous route. Let's assume an 8-bit char, a
16-bit int, and a 32-bit long (and because there's no
way to write a literal of type char, I'll need to use
a variable instead):

signed char sc = -3;
unsigned long ul = sc;

The procedure you've outlined would convert sc to an
unsigned int, getting 65533u, and then convert that value
to unsigned long, yielding 65533ul. Yet the correct
result is ULONG_MAX-2 == 4294967293. The intermediate
conversion has lost sign information that affects the
ultimate result.

> Apparently gcc disagrees.
>
> Am I doing something wrong somewhere?
>
> I should first cast into a long long THEN into an unsigned
> long long?


You should convert the signed int to unsigned long long
by adding or subtracting ULLONG_MAX+1 the appropriate number
of times: in this case, by adding it once.

--

 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      12-06-2007
Ben Pfaff wrote:
> jacob navia <> writes:
>
>> int main (void)
>> {
>> unsigned long long xx;
>> unsigned long long *x = (unsigned long long *) &xx;

>
> Why the cast? It should be unnecessary.
>
>> *x = -3;
>> *x = *x * *x;
>> if (*x != 9)
>> abort ();
>> return(0);
>> }
>>
>> lcc-win interprets
>> *x = -3;
>> as
>> *x = 4294967293;
>> since x points to an UNSIGNED long long.

>
> unsigned long long has to be at least 64 bits in size.
> 18446744073709551613 is the minimum correct value for *x here.
>
>> I cast the 32 bit integer -3 into an unsigned integer
>> then I cast the result to an unsigned long long.

>
> I don't see any cast to unsigned int in the above program.


Of course not. The casts were the result of loading a 32 bit constant
and extending it to a 64 bit constant in assembly.

I was missing the sign extend in the process.

Conceptually however, what is
(unsigned)-3

???

supposing sizeof(int)=4
sizeof(long long)=8

-3 is 4294967293

When you write "-3" that is a signed integer constant, in my system
32 bits, i.e. the above number.

When I do a sign extend, then it works
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      12-06-2007
Ben Pfaff wrote:
> Richard Heathfield <> writes:
>
>> jacob navia said:
>>> unsigned long long xx;
>>> unsigned long long *x = (unsigned long long *) &xx;
>>> *x = -3;
>>> *x = *x * *x;
>>> if (*x != 9)
>>> abort ();

>> It is deeply unlikely that *x will be 9 at this point.

>
> 2**64 - 3 == 18446744073709551613
> (18446744073709551613)**2 = 340282366920938463352694142989510901769
> 340282366920938463352694142989510901769 % 2**64 = 9
>
> At least according to the calculator I have here.


Yes, it should be 9. I was missing a sign extend when
converting a signed int into an unsigned long long.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      12-06-2007
wrote:
> jacob navia wrote:
>> I posted this to comp.std.c, but may be of interest here too:
>>
>> Consider this:
>>
>> extern void abort(void);
>> int main (void)
>> {
>> unsigned long long xx;
>> unsigned long long *x = (unsigned long long *) &xx;
>>
>> *x = -3;
>> *x = *x * *x;
>> if (*x != 9)
>> abort ();
>> return(0);
>> }
>>
>> lcc-win interprets
>> *x = -3;
>> as
>> *x = 4294967293;
>> since x points to an UNSIGNED long long.

>
> The minimum value for ULLONG_MAX is 18446744073709551615, so you
> should be getting a value of at least 18446744073709551613
>
>> I cast the 32 bit integer -3 into an unsigned integer
>> then I cast the result to an unsigned long long.

>
> Why did you do that?
>
>> Apparently gcc disagrees.
>>
>> Am I doing something wrong somewhere?

>
> Yes.
>
>> I should first cast into a long long THEN into an unsigned
>> long long?

>
> Why do you think that? Why are you using intermediaries?
>
> You should be converting -3 directly to unsigned long long. You should
> neither detour through unsigned int, nor detour through long long. The
> result should be ULLONG_MAX+1-3.


Yes, I was missing a sign extend.

But the abstract problem is still not clear to me. I mean when I see
a number like

-3

unadorned this is a signed integer constant. Since I am assigning it to
an unsigned value, I reinterpret the bits as an unsigned (this is my
mistake probably) and then convert THAT into an unsigned long long.


--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
jameskuyper@verizon.net
Guest
Posts: n/a
 
      12-06-2007
jacob navia wrote:
....
> Conceptually however, what is
> (unsigned)-3


It is a quantity which is utterly and completely irrelevant to this
code. It's value is UINT_MAX+1-3.

> supposing sizeof(int)=4
> sizeof(long long)=8
>
> -3 is 4294967293


I can't figure out any sense in which that statement is true. What is
true is that

(unsigned long long)-3 == ULLONG_MAX+1-3

and sizeof(int) has no relevance to that answer whatsoever.
 
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
problem with code - and code wariors thedarkman HTML 5 09-13-2010 11:40 PM
what is the difference between code inside a <script> tag and code in the code-behind file? keithb ASP .Net 1 03-29-2006 01:00 AM
Problem getting cookie from code-behind (worked in code-beside) Alan Silver ASP .Net 1 09-15-2005 05:23 PM
Problem with ejbdoclet--generated bean code is inheriting from "phantom" code... mwkohout@gmail.com Java 0 02-14-2005 06:06 PM
Fire Code behind code AND Javascript code associated to a Button Click Event =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?= ASP .Net 4 02-11-2004 07:31 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57