signed vs. unsigned & abs()

Since part of the calculation of abs(1-2) would involve a negative number, I'm not sure whether abs() can be performed on unsigned variables. My books may tell me somewhere, but I can't find anything. Would this work?

unsigned int A, B A = 20; B = 21; if(abs(A - B) = 1) {

Or do I have to use a signed variable?

SK

Reply to
Scott Kelley
Loading thread data ...

books

Nope. the abs() function takes an integer as argument. Therefore the compiler will convert the result of whater is between the brackets into an int.

Meindert

Reply to
Meindert Sprang

Assuming he is talking about C the over/underflow of the unsigned subtraction is perfectly well defined, and there is no need for any abs function. The result is always positive. The test should be (note ==):

if (1U == (A - B)) { ....

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

You need to check that. 20 decimal is 0x0014 hex. 21 decimal is 0x0015 hex. 0x0014 - 0x0015 = 0xffff (let's assume a 16-bit integer). 0xffff hex is 65535 decimal, which is a little bit different from 1.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Reply to
Tim Wescott

Yes, the argument will be converted, but it is implementation-defined.

Yes, the results of the subtraction are literally non-negative, but what the OP probably wants functionally is

if (A-B == 1 || B-A == 1) ...

--
Thad
Reply to
Thad Smith

That would depend entirely on how you (or somebody else, e.g. your C library implementor) decided to define abs().

No. Because there's at least one '=' character, and a prototype for abs(), missing in the above.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

All depends on what he is checking for. If he wants the result 1 my code is correct. If he wants the difference between 20 and 21 he wants to compare to UINT_MAX. The point is that there is no negative value for unsigned, nor any overflow.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

Then he should write what he wants. Maybe he shouldn't have defined the variables as unsigned, but then he would be subject to overflows causing undefined behaviour.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

No no no. This is spelled out in the C standard. When an unsigned quantity over (or under) flows, the value is resolved by repeatedly subtracting (or adding) UINT_MAX+1 from the result until the result is in the range 0..UINT_MAX. This specifies everything in all arithmetic types, 2's, 1's, or sign-magnitude. When a signed value over/underflows the result is either undefined or system defined behaviour, I forget which. Either is undesirable, because you don't always know what will happen.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

Which just goes to show, you have to know the question well and almost know the answer to have a good chance of getting something useful.

--
Thad
Reply to
Thad Smith

You need to check that.

Every 16-bit processor that _I've_ ever used was quite happy to take

65535U + 1 and give you 0 with no change, _not_ 65536. Ditto for larger integers, with appropriate adjustment for word size.
--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Reply to
Tim Wescott

That wouldn't work with the eZ80. In Zilog's compiler, the integer is 24 bit by default. If you want to enforce 16 bit, you havce to call them shorts (pants?). I suppose it's not "really" a 16 bit processor though.

Paul Burke

Reply to
Paul Burke

No, I don't need to "check that". The behaviour of unsigned integers is carefully spelled out in the C standard. All expressions are resolved modulo (UINT_MAX+1). This does not conflict with your or my statements above.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

It doesn't provide a guarantee because the standard (C or C++) only specify minimum sizes for a type and the relationship of sizes for the different types. A short could legitimately be 64-bit (as long as int and long were at least the same size).

Paul

Reply to
Paul Black

True, but the problem is not the under/overflow of the unsigned quantity. The problem is that the abs() function accepts a signed integer (assuming stdlib), and that the argument 'A-B' is unsigned. The means that the compiler will have to convert the unsigned into a signed, which is implementation-defined for non-overlapping values.

For example, assuming 16 bit int/unsigned, an implementation could in theory convert the entire range of 32768-65535 unsigned into 32767 signed. This is not so unreasonable for DSP applications that want to do saturated math. For those implementations, the OP program would fail.

Reply to
Artenz

Why, in heavens name, would anybody in their right mind apply the abs function to an unsigned quantity? The value is already known to be positive. Of course idiotic code would fail.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

I was using a 16-bit processor as an example. In your 24-bit case you'd roll 0xffffff over to 0, a 32-bit would roll 0xffffffff to 0, a 17-bit processor would roll 0x1ffff to 0, etc.

The Motorola 56000 was a native 24-bit machine, so char, short and int were all 24 bits, and long was probably 48. You have to adjust your expectations to the machine.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Reply to
Tim Wescott

Look up four responses and check that. On a compliant machine 20U - 21U = UINT_MAX, _not_ one as you stated.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Reply to
Tim Wescott

I never stated 20U - 21U == 1. Its all still quoted above. I did specify a test:

if (1U == (A - B)) { ....

which would obviously fail on those values. If the OP wants to check that the difference between A and B is exactly 1, he can write what he means, such as:

if ((1U == (A - B)) || (1U == (B - A))) { ....

and no abs() functions should ever come into it. Once more, applying abs to an unsigned quantity is completely ridiculous.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.