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
Richard Heathfield wrote:
>> 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.
>


????

Bugs are non conforming by definition...

)


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


Because that is part of a bigger program that I got
and I isolated (after some hours of debugging) the code
that exposes the bug in my software! (lcc-win)

I assure you that I know the multiplication tables, but thanks
for the answer anyway.

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

> Richard Heathfield <> writes:
>
>> It is deeply unlikely that *x will be 9 at this point.

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


I did the math before posting, and removed an entire paragraph about this
(further down the article), but evidently I omitted to remove the above
sentence. Oops, sorry etc.

--
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
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      12-06-2007
Eric Sosman said:

> ULLONG_MAX is at
> least 18446744073709551615, so ULLONG_MAX-2 (the required
> result) is at least 18446744073709551614.


ITYM 18446744073709551613

--
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
 
Richard Tobin
Guest
Posts: n/a
 
      12-06-2007
In article <fja0jo$u4u$>, jacob navia <> wrote:

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


Is there supposed to be any significance to using *x instead of xx?
The types of *x and xx are the same, so the same conversions should
apply.

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


Strictly speaking, there are no negative integer constants. The syntax
for integer constants doesn't allow minus signs. It's a constant
expression of type int (the result of applying unary minus to the
integer constant 3).

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


Yes, this is your mistake. You have an int that you are assigning to
an unsigned long long, so you should do that conversion in a single
step.

The final answer will be 9 as your code implies, since the result of
the conversion will be equal to -3 (mod N), where log2(N) is the
number of bits in an unsigned long long, and if

a = A (mod N) and b = B (mod N)
then
a*b = A*B (mod N)

-- Richard
--
:wq
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      12-06-2007
In article <fja0pv$u4u$>, jacob navia <> wrote:

>Bugs are non conforming by definition...


Not necessarily - a bug in code that implements undefined behaviour
just results in some other undefined behaviour, which is equally
conformant

-- Richard
--
:wq
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-07-2007
Richard Heathfield wrote:
> Eric Sosman said:
>
>> ULLONG_MAX is at
>> least 18446744073709551615, so ULLONG_MAX-2 (the required
>> result) is at least 18446744073709551614.

>
> ITYM 18446744073709551613


YTC.

--
Eric Sosman
lid
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      12-07-2007
jacob navia wrote:
> [...]
> 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.


Yes, that's the error. Conversion from one type to another
involves the *value* being converted, not its representation.
As a related example consider

signed char sc = -1;
int a = sc;
unsigned int b = sc;

In neither case will "reinterpret the bits and then convert"
produce the correct answer. What you're doing is more akin to

unsigned int c = (unsigned char)sc;

--
Eric Sosman
lid
 
Reply With Quote
 
Jack Klein
Guest
Posts: n/a
 
      12-07-2007
On Thu, 06 Dec 2007 23:09:24 +0100, jacob navia <>
wrote in comp.lang.c:

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


Yes, I believe you are.

The C standard's wording on initializing scalars (6.7.8 P11) states:

"The initializer for a scalar shall be a single expression, optionally
enclosed in braces. The initial value of the object is that of the
expression (after conversion); the same type constraints and
conversions as for simple assignment apply, taking the type of the
scalar to be the unqualified version of its declared type."

Referring to "Simple assignment" 6.5.26.2 P2:

"In simple assignment (=), the value of the right operand is converted
to the type of the assignment expression and replaces the value stored
in the object designated by the left operand."

Putting these together, the integer constant expression -3, of type
int, is converted to type unsigned long long. There are no
intermediate conversions specified or implied to unsigned int or
signed long long. Your compiler might take these intermediate steps,
under the as-if rule, but only if you produce the same results as a
direct conversion.

And the correct result is (ULLONG_MAX + 1) - 3;

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


No, I think not. What would the result be if you had written either
of these:

*x = -3ULL;

....or:

*x = (unsigned long long)3;

I think you are getting hung up on the details of how you code the
conversion in your compiler, and losing sight of the meaning of the
expression in the language.

The conversion, like all such in C, is defined in terms of value, not
of steps or types to achieve it.

As a practical matter, I suspect the simplest method to get the
correct result would be to convert the signed int constant to signed
long long, then to unsigned long long.

Note the following program, and its output when run in VS 2005
Express, which does not support much of C99 but does support the long
long types:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
unsigned long long x = (unsigned int)-3;
unsigned long long y = (unsigned long long)-3;
unsigned long long z = -3;
unsigned long long a = (long long)-3;
printf("x = %llu\ny = %llu\nz = %llu\na = %llu\n",
x, y, z, a);
return 0;
}

Output:

x = 4294967293
y = 18446744073709551613
z = 18446744073709551613
a = 18446744073709551613

So I suspect your compiler will generate the proper value using the
signed int to signed long long to unsigned long long series of
conversions.

> Thanks for your help.


You're welcome.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
Reply With Quote
 
somenath
Guest
Posts: n/a
 
      12-07-2007
On Dec 7, 4:02 am, Ben Pfaff <b...@cs.stanford.edu> wrote:
> Richard Heathfield <r...@see.sig.invalid> 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.



I beg your pardon for asking basic question in the flow of high level
technical discussion .I am sorry if it break the flow of the
discussion .

My doubt is about the following lines and the result.

1) *x = -3;
2) *x = *x * *x;

After executing line 1) *x will be equal to at least
18446744073709551613.
And after executing line 2)
*x is 3. But my doubt is how it is possible?

My doubt is while executing *x * *x is *x again converted to 3 ?
That's why 3 * 3 is 9? If yes why it is required?
Because now *x is not negative so it is not required to be converted
to unsigned.






 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      12-07-2007
somenath wrote:
> On Dec 7, 4:02 am, Ben Pfaff <b...@cs.stanford.edu> wrote:
>> Richard Heathfield <r...@see.sig.invalid> 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.


Actually, it's guaranteed to be 9.

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

>
>
> I beg your pardon for asking basic question in the flow of high level
> technical discussion .I am sorry if it break the flow of the
> discussion .
>
> My doubt is about the following lines and the result.
>
> 1) *x = -3;
> 2) *x = *x * *x;
>
> After executing line 1) *x will be equal to at least
> 18446744073709551613.
> And after executing line 2)
> *x is 3. But my doubt is how it is possible?


*x isn't 3 at that point. It should be 9.

> My doubt is while executing *x * *x is *x again converted to 3 ?
> That's why 3 * 3 is 9? If yes why it is required?


No. It's a little more interesting than that. All of the following
expressions are intended to be interpreted mathematically, rather than
as C expressions that could (and would) overflow. The value that should
be stored in *x in step 1 is obtained by adding ULLONG_MAX + 1 to -3 as
many times as are needed to generate a value between 0 an ULLONG_MAX,
inclusive. In this case, it only has to be added one time:

ULLONG_MAX + 1 - 3

Now, let's calculate the mathematical value of the square of that value:

(ULLONG_MAX + 1)^2 -2*3*(ULLONG_MAX + 1) + 9

= (ULLONG_MAX - 5)*(ULLONG_MAX + 1) + 9

The value that is actually stored in *x by step 2 is obtained from that
mathematical value by (conceptually) subtracting ULLONG_MAX + 1 as many
times as needed until the result is between 0 and ULLONG_MAX, inclusive.
I hope it's clear that it needs to be subtracted exactly ULLONG_MAX-5
times, giving a result of 9. This isn't a coincidence, but a normal
consequence of modulus arithmetic. In reality, of course, no
subtractions are actually carried out; the required result is obtained
naturally as a result of properly implemented unsigned multiplication.
The explanation given above can be generalized to prove that

((a mod c) * (b mod c)) mod c = (a*b) mod c

(I hope I got the modulus notation right - it's been nearly three
decades since I last used it)
In this case, a and b are -3, and c is ULLONG_MAX + 1
 
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