Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Unsinged types

Reply
Thread Tools

Unsinged types

 
 
Malcolm McLean
Guest
Posts: n/a
 
      07-21-2012
בתאריך יום שבת,21 ביולי 2012 18:27:33 UTC+1, מאת Bart:
>Malcolm McLean&qu <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > The compiler has no way of knowing that a cursor position of 3 billion
> > pixels is completely ridiculous.

>
> Not completely. A 1 pixel x 3 billion pixel black white image only uses
> 375MB.
>

That's why int should be 64 bits on 64 bit machines.

You could technically have a 3 billion x 1 pixel image on a 32 bit machine,but you'll only have one of them in memory at any one time,and it can't bea coloured image. But a lot of operating systems won't allow such a big array. It's annoying that signed int doesn't handle this case, but the situation is rare enough that we can live with it.

Most people with a need to handle such images will move to 64 bit operatingsystems with more memory. If int is 64 bits, the code will work without any need for a rewrite.
 
Reply With Quote
 
 
 
 
Seungbeom Kim
Guest
Posts: n/a
 
      07-21-2012
On 2012-07-20 14:41, Eric Sosman wrote:
> On 7/20/2012 5:11 PM, Seungbeom Kim wrote:
>>
>> Things that you assume should be non-negative often turn out to be
>> not always so. For example, though no one thinks of a negative day
>> of the month, the tm_* members of struct tm are signed, because you
>> sometimes need to be able to represent out-of-range values.

>
> It's also a way to help with some calculations. For example,
> you can start from a given date, subtract fourteen from tm_mday,
> re-normalize, and easily find out "What date was a fortnight
> before January 5?"


Exactly.

>> In addition, "unsigned" in C does not only mean non-negativity,
>> but also implies modulo arithmetic; you can't even get the difference
>> between two unsigned values in the most natural way (a - b).

>
> You can't do that with signed integers, either.


Of course, signed integers are not without their limits (and the design
limits should lie safely within the environmental limits).

However, *most* of the values we deal with are in small ranges that are
not too far from zero; ranges near INT_MAX, for example, but far from
zero are uncommon, if any, and they may need an upgrade to a larger
integer type anyway.

Given that, getting around in signed is usually safe, as you're near
the center, far from the edges, of the field. Doing that in unsigned,
however, is like playing near the edge and risks falling off.


,- usually here
*****
signed [-------+-------+-------+-------]XXXX DANGER
| | |
-INT_MAX 0 INT_MAX UINT_MAX
| | |
unsigned DANGER XXXX[-------+-------+-------+-------]


> And in the cases where naive subtraction doesn't work, you don't
> just get a possibly surprising but predictable outcome: You get
> undefined behavior.


True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
how predictable it is, and failing to take that into account is a bug,
just as getting undefined behavior from signed arithmetic overflow is.

>> And the
>> unsignedness is contagious, so (unsigned_value > -1) may not be true
>> and ((unsigned)negative_value > 100) may be true to your surprise.

>
> Oh, come on! You might just as well complain about double-ness
> being "contagious."


Their "contagiousnesses" per se may be similar, but their effects are
different; conversion from integer to double doesn't (usually) change
the value being converted, or the result of the comparison at least,
but conversion from signed to unsigned often does, often in a very
surprising way, which is exactly my point in the paragraph above.

> Besides, why blame the surprises on the unsigned operand? They
> don't arise from either one of the operands in isolation, but from
> the combination of the two -- so the signed operand is every bit as
> much to blame as the unsigned. If you blame one, you should blame
> the other equally.[*]
>
>[*] Okay, that doesn't always happen in real life: Doheny was
> acquitted of offering the bribe that Fall was convicted of taking.
> But Roaring Twenties jurisprudence is a poor model for programming!


Sorry, I don't understand the footnote.

Anyway, you're right that the surprises arise from the combination.
If your values are usually closer to the upper limit of signed (say,
INT_MAX) than to zero, then signed gets in the way more often and may
deserve more "blame." If, on the other hand, they are usually closer
to the lower limit of unsigned, i.e. zero, then unsigned more often
gets in the way. If both cases happen equally, you may want to blame
them equally. In most of the cases I encounter, they don't.
Your mileage may vary, though.

>> The reality is, however, that everyone thinks differently, similar
>> debates are endless, and that unsigned is widely used for other things
>> (e.g. counts and sizes) even in the standard library, so you have to
>> live with unsigned being everywhere, and learn to be careful when
>> mixing signed and unsigned.

>
> ... or when mixing signed integer with long double complex, or
> when mixing unsigned long with pointer-to-pointer-to-T, or ... In
> fact, your recommendation to "be careful when..." can be improved
> by deleting "when" and everything after it. Just be careful, okay?


It's not a unanimous improvement, as it makes my statement more general
and more "vacuously true." Maybe I should have said "be *more* careful"
to be clearer, but I won't delete the when-clause. I don't object to
your being careful in everything, though.

--
Seungbeom Kim
 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      07-21-2012
"Seungbeom Kim" <(E-Mail Removed)> wrote in message
news:juf5mm$mr$(E-Mail Removed)...
> On 2012-07-20 14:41, Eric Sosman wrote:
>> On 7/20/2012 5:11 PM, Seungbeom Kim wrote:


>>> In addition, "unsigned" in C does not only mean non-negativity,
>>> but also implies modulo arithmetic; you can't even get the difference
>>> between two unsigned values in the most natural way (a - b).

>>
>> You can't do that with signed integers, either.

>
> Of course, signed integers are not without their limits (and the design
> limits should lie safely within the environmental limits).
>
> However, *most* of the values we deal with are in small ranges that are
> not too far from zero; ranges near INT_MAX, for example, but far from
> zero are uncommon, if any, and they may need an upgrade to a larger
> integer type anyway.
>
> Given that, getting around in signed is usually safe, as you're near
> the center, far from the edges, of the field. Doing that in unsigned,
> however, is like playing near the edge and risks falling off.
>
>
> ,- usually here
> *****
> signed [-------+-------+-------+-------]XXXX DANGER
> | | |
> -INT_MAX 0 INT_MAX UINT_MAX
> | | |
> unsigned DANGER XXXX[-------+-------+-------+-------]
>
>
>> And in the cases where naive subtraction doesn't work, you don't
>> just get a possibly surprising but predictable outcome: You get
>> undefined behavior.

>
> True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
> how predictable it is


You've put the point across much better than I've ever been able to, in many
more posts (-1<5 is true, -1<5u is false, etc.)

But, the language is apparently always right. Even if it's due to 'existing
practice'.

--
bartc

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-21-2012
Malcolm McLean <(E-Mail Removed)> writes:

> בתאריך יום שבת, 21 ביולי 2012 17:48:51 UTC+1, מאת Ben Bacarisse:
>> Malcolm McLean http://www.velocityreviews.com/forums/(E-Mail Removed) writes:
>>
>> These are arguments are about code that no one has, or should, write.
>> It's a straw man. Why not just show how much simpler your code is than
>> mine when getcursorposition uses int *s rather than unsigned int *s?
>> That will make it clear just how much damage the using of unsigned has
>> introduced.
>>

> void drawoctogonroundcursor(void)
> {
> int octx[8];
> int octy[8];
> int cx, cy;
> int d = 3; /* this gives the size of the octogon step */
>
> getcursorposition(&cx, &cy);
> octx[0] = cx-d; octy[0] = cy-2*d;
> octx[1] = cx+d; octy[1] = cy-2*d;
> octx[2] = cx+2*d; octy[2] = cy-d;
> octx[3] = cx+2*d; octy[3] = cy+d;
> octx[4] = cx+d; octy[4] = cy+2*d;
> octx[5] = cx-d; octy[5] = cy+2*d;
> octx[6] = cx-2*d; octy[6] = cy+d;
> octx[7] = cx-2*d; octy[7] = cy-d;
>
> drawpolygon(octx, octy, ;
>
> }
>
> There's no messing about.


So to sum up, the messing about caused by an (in my opinion
inappropriate) use of unsigned is a declaration and two assignments. I
don't see that as a strong reason to discourage their use, especially in
more appropriate situations. For example, is the third parameter of
drawpolygon signed or unsigned?

I don't want to be dogmatic about this -- I am sure there are cases
where someone having chosen the "wrong" signedness causes problems, but
I don't think this is a clear-cut example. In contrast, the cases where
you need to pure binary semantics of C's unsigned types are, in my
experice, more common (but then I used to write cryptographic code).

> We can focus completely on the drawing
> logic, which I might have got wrong.


Well, I assumed you meant a regular octagon which make a loop the
obvious way to go, but that's not really the issue here.

--
Ben.
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      07-21-2012
בתאריך יום שבת,21 ביולי 2012 22:35:35 UTC+1, מאת Ben Bacarisse:
> Malcolm McLean &lt;(E-Mail Removed)&gt; writes:
>
> So to sum up, the messing about caused by an (in my opinion
> inappropriate) use of unsigned is a declaration and two assignments.
>
> Well, I assumed you meant a regular octagon which make a loop the
> obvious way to go, but that's not really the issue here.
>

A regular octagon would have to take reals. Then you don't see the problem,as there isn't an unsigned real type. A drawrectangle() could reasonably be written to take four parameters, so here you don't really see the problemeither. You might need an ugly cast, but there's not too damaging.
The problem comes when you start passing about integers by indirection. A sane integer-based drawpolygon() function has to accept a pointer to signed integers, maybe wrapped in a structure. But cx and cy are unsigned. So either you cast every assignment, which is a lot of extra characters, or you create special variables signed_cx and signed_cy. Both are a real nuisance.
I know that you can specify the octogon as offsets and then fill the bufferin a loop. There are ways round it. But the types of integers shouldn't bea factor in that consideration about how to write the function.


 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-21-2012
Eric Sosman <(E-Mail Removed)> writes:

> On 7/20/2012 5:11 PM, Seungbeom Kim wrote:
>> On 2012-07-19 15:47, Ben Pfaff wrote:
>>>
>>> Many quantities are naturally unsigned; for example, counts and
>>> sizes. These quantities are most naturally modeled with unsigned
>>> types.

>>
>> Things that you assume should be non-negative often turn out to be
>> not always so. For example, though no one thinks of a negative day
>> of the month, the tm_* members of struct tm are signed, because you
>> sometimes need to be able to represent out-of-range values.

>
> It's also a way to help with some calculations. For example,
> you can start from a given date, subtract fourteen from tm_mday,
> re-normalize, and easily find out "What date was a fortnight
> before January 5?" [snip unrelated]


Can also easily be done using unsigned types.
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-22-2012
Seungbeom Kim <(E-Mail Removed)> writes:

> On 2012-07-20 14:41, Eric Sosman wrote:

[snip]
>> And in the cases where naive subtraction doesn't work, you don't
>> just get a possibly surprising but predictable outcome: You get
>> undefined behavior.

>
> True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
> how predictable it is, [snip]


That's an overstatement. It may not be useful in ways that
you would like it to be, or in all the cases you would like
it to be, but there still are lots of cases where it is
useful. To give one example, if we want to test if
variable 'i' is in the range [20 .. 30), with signed
arithmetic that takes two comparisons, but with unsigned
arithmetic this can be done with one comparison:

if( (i-20u) < 10 ) ...

Unsigned arithmetic doesn't behave in a way that most
people are used to, but the behavior it has still is
quite useful, in lots of different ways.
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      07-22-2012
"Tim Rentsch" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Seungbeom Kim <(E-Mail Removed)> writes:
>
>> On 2012-07-20 14:41, Eric Sosman wrote:

> [snip]
>>> And in the cases where naive subtraction doesn't work, you don't
>>> just get a possibly surprising but predictable outcome: You get
>>> undefined behavior.

>>
>> True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
>> how predictable it is, [snip]

>
> That's an overstatement. It may not be useful in ways that
> you would like it to be, or in all the cases you would like
> it to be, but there still are lots of cases where it is
> useful. To give one example, if we want to test if
> variable 'i' is in the range [20 .. 30), with signed
> arithmetic that takes two comparisons, but with unsigned
> arithmetic this can be done with one comparison:
>
> if( (i-20u) < 10 ) ...


You're replacing two comparisons, with a comparison and a subtraction, and
now have code that will cause people to scratch their heads (with the
mysterious introduction of '10' and '20u') instead of just writing:

if (i>=20 && i<30)

and leaving it to the compiler to sort out, as we're constantly told to do.
It's possible also that i will be <20, so only one comparison gets done
anyway.

(I do sometimes use the idiom, in assembly, but when i needs to be offset
to start at zero anyway.)

> Unsigned arithmetic doesn't behave in a way that most
> people are used to


'Unintuitive'

--
Bartc

 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      07-22-2012
Seungbeom Kim <(E-Mail Removed)> writes:
> On 2012-07-20 14:41, Eric Sosman wrote:
> > And in the cases where naive subtraction doesn't work, you don't
> > just get a possibly surprising but predictable outcome: You get
> > undefined behavior.

>
> True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
> how predictable it is, and failing to take that into account is a bug,
> just as getting undefined behavior from signed arithmetic overflow is.


unsigned int find_new_right(unsigned int old_left,
unsigned int old_right,
unsigned int new_left)
{
return new_left + (old_right - old_left);
}

In calling find_new_right(5,2,100) I have "failed to take into account"
that the 2U-5U within its evaluation is 4294967293U.

However, there's no bug.

So it's not comparable to the undefined behaviour from overflow when
using signed arithmetic.

Phil
--
> I'd argue that there is much evidence for the existence of a God.

Pics or it didn't happen.
-- Tom (/. uid 822)
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      07-22-2012
"Phil Carmody" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Seungbeom Kim <(E-Mail Removed)> writes:


>> True. But (2U - 5U) yielding 4294967293U is not very useful, no matter
>> how predictable it is, and failing to take that into account is a bug,
>> just as getting undefined behavior from signed arithmetic overflow is.

>
> unsigned int find_new_right(unsigned int old_left,
> unsigned int old_right,
> unsigned int new_left)
> {
> return new_left + (old_right - old_left);
> }
>
> In calling find_new_right(5,2,100) I have "failed to take into account"
> that the 2U-5U within its evaluation is 4294967293U.
>
> However, there's no bug.


Yes, you sometimes get these seriously weird-looking intermediate results
that often magically get cancelled out. But not always.

Try (2u - 5u) > 100u;

--
Bartc


 
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
Unsinged types Jase Schick C Programming 11 07-23-2012 10:12 PM
Comparing singed to unsinged warning Nevil Lesdog C Programming 7 08-24-2007 01:45 AM
writing binary data whose size exceeds unsinged it mohammad.nabil.h@gmail.com C Programming 14 01-28-2006 12:18 PM
warning - comparing a signed value to an unsinged value Kevin Goodsell C Programming 30 10-22-2003 12:12 PM
Unsinged char to int Joseph Suprenant C Programming 2 08-18-2003 04:09 PM



Advertisments