473,505 Members | 15,036 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this a guaranteed signed/unsigned conversion?

Consider:

#include <stdlib.h>

/* An elementary optimizer is expected to remove most code */
/* Return the absolute value */
unsigned long ulabs(long j)
{
if (0 == LONG_MIN + LONG_MAX) {
if (j < 0) return -j;
else return j;
}
else if (LONG_MIN == j) return 1U + j + ULONG_MAX;
else if (j < 0) return -j;
else return j;
} /* ulabs */

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.

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

Nov 14 '05 #1
7 1831
CBFalconer wrote:
Consider:

#include <stdlib.h>

/* An elementary optimizer is expected to remove most code */
/* Return the absolute value */
unsigned long ulabs(long j)
{
if (0 == LONG_MIN + LONG_MAX) { Make that <= if (j < 0) return -j;
else return j;
}
else if (LONG_MIN == j) return 1U + j + ULONG_MAX; why not:
else if (j>0)
return j;
else if (j>= -LONG_MAX)
return -j;
else
return ((unsigned long)-(j-(LONG_MIN+LONG_MAX)))-(LONG_MIN+LONG_MAX); else if (j < 0) return -j;
else return j;
} /* ulabs */

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.


If you assume that all bits are used and symmetrically, your
code will work.
Otherwise: what about LONG_MIN < -LONG_MAX-1?

See my annotations. (Burned my dinner over it, so I hope I
did not goof ;-))

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #2


CBFalconer wrote:
Consider:

#include <stdlib.h>

/* An elementary optimizer is expected to remove most code */
/* Return the absolute value */
unsigned long ulabs(long j)
{
if (0 == LONG_MIN + LONG_MAX) {
if (j < 0) return -j;
else return j;
}
else if (LONG_MIN == j) return 1U + j + ULONG_MAX;
else if (j < 0) return -j;
else return j;
} /* ulabs */

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.


Let's see: The first part handles ones' complement and
signed magnitude, where negation of LONG_MIN is possible.
Straightforward, and correct as far as I can see. By the
way, the `0 == LONG_MIN + LONG_MAX' test could be made
with `#if' instead of with `if', reducing the reliance on
the optimizer's ability to eliminate dead code.

In the two's complement part, the conversion of LONG_MIN
seems wordier than need be: as far as I can tell, it gives
the same result as `return j'. Either way, the result should
be correct if ULONG_MAX == LONG_MAX * 2UL + 1UL, which is the
case on every implementation I've run into. However, I think
the Standard permits perversity, and two kinds of perversity
could cause trouble:

ULONG_MAX == LONG_MAX (that is, the sign bit of
`long' corresponds to a padding bit in `unsigned
long'). In this case your quest is hopeless --
but your assumption excludes it, so perhaps we
needn't worry. Another #if could trigger an
appropriate #error directive if desired.

ULONG_MAX == LONG_MAX * 4UL + 3UL (for example;
this happens if `long' has padding bits that
correspond to value bits of `unsigned long').
In this case, ulabs() would return much too
large a value.

I think there's a simple repair, though. For a negative
two's complement value, first add unity, then negate (this is
known to be safe), then convert to `unsigned long', and finally
add another unity to cancel the first (now negated) addition:

if (j < 0) return -(j + 1) + 1UL;
else return j;

(Note that the first `return' expression is *not* equivalent
to `1UL - (j + 1)', because the conversion to `unsigned long'
occurs at the wrong point in the proceedings. I'd recommend
a goodly block of comments here to discourage tidy-minded
people from making the "obvious" rearrangement -- either that,
or write it as `-++j+1UL' to scare them all away. ;-)

As far as I can see, this will cover all cases except
ULONG_MAX == LONG_MAX, already excluded by assumption. It
would even handle ones' complement and signed magnitude,
eliminating the special case at the cost of a smidgen of
unnecessary code.

Of course, I may have overlooked something. "Trust,
but verify."

--
Er*********@sun.com

Nov 14 '05 #3
In article <42***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
Consider:

#include <stdlib.h>

/* An elementary optimizer is expected to remove most code */
/* Return the absolute value */
unsigned long ulabs(long j)
{
if (0 == LONG_MIN + LONG_MAX) {
if (j < 0) return -j;
else return j;
}
else if (LONG_MIN == j) return 1U + j + ULONG_MAX;
else if (j < 0) return -j;
else return j;
} /* ulabs */

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.


I think it will work; I believe it is guaranteed that LONG_MIN +
LONG_MAX is either 0 or -1.

What about this:

unsigned long ulabs (long j) {
return j >= 0 ? (unsigned long) j : 0ul - j;
}

I think this should work. The case j >= 0 is obviously fine. If j < 0,
then evaluating (0ul - j) will convert j to unsigned long; since the
value of j cannot be represented ULONG_MAX + 1 will be added as often as
needed (that is once) giving (j + ULONG_MAX + 1). The subtract operation
gives - (j + ULONG_MAX + 1) and since the result is negative, ULONG_MAX
+ 1 is again added as often as necessary (that is once), giving -j.
Nov 14 '05 #4
On Fri, 20 May 2005 20:08:26 +0000, CBFalconer wrote:
Consider:

#include <stdlib.h>

/* An elementary optimizer is expected to remove most code */
/* Return the absolute value */
unsigned long ulabs(long j)
{
if (0 == LONG_MIN + LONG_MAX) {
if (j < 0) return -j;
else return j;
}
else if (LONG_MIN == j) return 1U + j + ULONG_MAX;
That's incorrect if ULONG_MAX is over twice as large as LONG_MAX.
Why not just return 1UL + LONG_MAX.
else if (j < 0) return -j;
else return j;
} /* ulabs */

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.


I've used similar to the following in the past:

unsigned long ulabs(long j)
{
return j>=0 ? (unsigned long)j : -(unsigned long)j;
}

Lawrence
Nov 14 '05 #5
Lawrence Kirby wrote:
I've used similar to the following in the past:

unsigned long ulabs(long j)
{
return j>=0 ? (unsigned long)j : -(unsigned long)j;
}


I wonder if anyone ever made a C implementation that allows you to
choose at compile-time whether integers are stored as one's complement,
two's complement or signed magnitude? Of course, emulating operations on
a data type that is not native to the underlying hardware would be very
slow, but I imagine it would be useful for testing your code's
portability to esoteric computers without having them available on the
desktop.

The closest I know of is how GCC allows you to choose whether char is
signed or unsigned.

--
Simon.
Nov 14 '05 #6
Lawrence Kirby wrote:
On Fri, 20 May 2005 20:08:26 +0000, CBFalconer wrote:

.... snip ...

Is this guaranteed to convert all long values to their absolute
unsigned long equivalent, assuming that the desired result is
representable as an unsigned long. Does it work over 2's, 1's
complement and sign-magnitude? Is there a better method? labs()
is not guaranteed.


I've used similar to the following in the past:

unsigned long ulabs(long j)
{
return j>=0 ? (unsigned long)j : -(unsigned long)j;
}


I can see nothing wrong with that. Why did I make it so
complicated?

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
Nov 14 '05 #7

"Simon Biber" <ne**@ralmin.cc> wrote
I wonder if anyone ever made a C implementation that allows you to choose
at compile-time whether integers are stored as one's complement, two's
complement or signed magnitude?

That would be a really useful tool. Something that compiles C to byte code,
and then produces output based on all sorts of configurable and maybe
eccentric assumptions about type representation.
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
6445
by: MiniDisc_2k2 | last post by:
Okay, here's a question about the standard. What does it say about unsigned/signed mismatches in a comparison statement: char a = 3; unsigned char b = 255; if (a<b) Now what's the real...
8
2221
by: Rade | last post by:
Following a discussion on another thread here... I have tried to understand what is actually standardized in C++ regarding the representing of integers (signed and unsigned) and their conversions....
9
4942
by: Fred Ma | last post by:
Hello, I've been trying to clear up a confusion about integer promotions during expression evaluation. I've checked the C FAQ and C++ FAQ (they are different languages, but I was hoping one...
10
15612
by: tinesan | last post by:
Hello fellow C programmers, I'm just learning to program with C, and I'm wondering what the difference between signed and unsigned char is. To me there seems to be no difference, and the...
2
1682
by: G Fernandes | last post by:
Hello, I have a question about using an unsigned int and a signed long int in an expression (where UINT_MAX > LINT_MAX). Based on the conversion rules, the unsigned int will be convered to...
14
9288
by: junky_fellow | last post by:
Can anybody please explain this: When a value with integer type is converted to another integer type other than _Bool, if the new type is unsigned, the value is converted by repeatedly...
19
2045
by: junky_fellow | last post by:
How the unsigned to signed integet conversion is done ? For eg: unsigned int ui = 100; int si = ui; What will be the value if "si" is printed ? How this conversion is done ? Thanx for any...
6
2335
by: NM | last post by:
I am given an int and have to tell whether the bit representation of that int is a palindrome or not. Here is what I have come up with bool isIntPalindrome(int num) { unsigned int temp = num;...
7
5024
by: somenath | last post by:
Hi All, I am trying to undestand "Type Conversions" from K&R book.I am not able to understand the bellow mentioned text "Conversion rules are more complicated when unsigned operands are...
0
7216
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7303
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7018
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7471
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
5028
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4699
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3176
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
754
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
407
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.