469,649 Members | 1,393 Online

# bitwise absolute value

I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers. Is there a portable/standard way
to do this? Or are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #1
34 16266 "Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message

are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

Integers can be 16, 32 or very rarely another number of bits. chars are
usually 8 bits but 9 or 32 has occasionally been reported.

using ( sizeof(int) * CHAR_BIT ) will be reasonably portable, but vulnerable
to padding bits. INT_MAX will give you the maximum value of an integer.
There is also no guarantee that your system uses two's complement
representation of negative numbers.

So it is quite easy to make your construct portable to any architecture you
are likely to encounter in practise, but very difficult to do so in a
perfectly compliant manner. Since your problem looks like a brainteaser
rather than a real programming construct, it is probably worth pinting out
the pitfalls to whoever set it.

Nov 13 '05 #2
On Sun, 07 Sep 2003 20:06:20 +0000, Christopher Benson-Manica wrote:
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers.

That can be easily fixed. The more insidious assumption is that it assumes
twos-complement representation of integers.

Josh
Nov 13 '05 #3

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:bj**********@chessie.cirr.com...
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers. Is there a portable/standard way to do this? Or are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org

Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code. It avoids a branch which is
important on today's processors.
Be aware that Sun has a patent on this method.
Carsten Hansen
Nov 13 '05 #4
Carsten Hansen <ha******@worldnet.att.net> spoke thus:
(x^((~((x>>31)&1))+1)) + ((x>>31)&1)
Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code. It avoids a branch which is
important on today's processors.
Be aware that Sun has a patent on this method.

Whoops... What's the rationale behind that though? I'm trying to wrap my
brain around the logic... And how does it avoid a branch?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #5

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:bj**********@chessie.cirr.com...
Carsten Hansen <ha******@worldnet.att.net> spoke thus:
(x^((~((x>>31)&1))+1)) + ((x>>31)&1)
Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code. It avoids a branch

which is important on today's processors.
Be aware that Sun has a patent on this method.

Whoops... What's the rationale behind that though? I'm trying to wrap my
brain around the logic... And how does it avoid a branch?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |

Traditionally you take the absolute value by doing something like

if (x < 0)
y = -x;
else
y = x;

Or maybe

y = (x < 0) ? -x : x;

But this involves a comparison and a branch. If the sign of x is random, the
branch prediction is of no value. Hence the processor will stall in 50% of
In compression code this is common case. You remove all redundancy, and the
rest is white noise that you have to encode.
Today it is in general better to do a few extra instructions if that will
avoid a branch. "Keep the processor busy".
Intel's compiler will do this optimization.
Carsten Hansen
Nov 13 '05 #6
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote in message news:<bj**********@chessie.cirr.com>...
I'm trying to compute the absolute value of an integer using only bitwise
operators...
Why?
int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers.
And two's complement representation, and sign bit propogating right
shifts, and possibly an absence of trap representations.

In a clc sense, it doesn't work at all.
Is there a portable/standard way to do this?
(x < 0 ? -x : x)

Note that it does assume that INT_MIN is negatable, which isn't the
case in 2c.
Or are ANSI integers always 32 bits?
Definitely not. An int must have at least 16 (value+sign) bits, a long
must have at least 32.
If not, is using sizeof(int) * 8 - 1 as the shift value an acceptable
alternative?

No, since CHAR_BIT need not be 8 and the integer can be padded.

--
Peter
Nov 13 '05 #7
Peter Nilsson <ai***@acay.com.au> spoke thus:
Why?
It was an assignment for the intro-to-C class at school and I was trying to
help a friend... and it was a macho thing to prove I could do it ;)
In a clc sense, it doesn't work at all.
By "works," of course, I meant "produces correct results on my implementation."
(x < 0 ? -x : x)

Certainly would have been my first choice, but all conditional operators were
explicitly forbidden by the assignment. The 32-bit integer assumption was
explicitly permitted, and two's complement represenation was implied. Since
the code was only required to work on a specific implementation (an i386 Linux
box, I believe), these assumptions were acceptable in the context of the
assignment.

Is this question impossible to answer in a strictly ANSI-compliant way, then?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #8
Carsten Hansen <ha******@worldnet.att.net> spoke thus:
Whoops... What's the rationale behind that though? I'm trying to wrap my
brain around the logic... And how does it avoid a branch?

I probably should have been clear earlier - this was an assignment a friend of
mine had, and conditional operations were explictly forbidden.

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Nov 13 '05 #9

On Mon, 8 Sep 2003, Christopher Benson-Manica wrote:

Peter Nilsson <ai***@acay.com.au> spoke thus:
Why?

It was an assignment for the intro-to-C class at school and I was trying to
help a friend... and it was a macho thing to prove I could do it ;)

(BTW, I'm in a course this year whose first lab consists entirely of
about a dozen of these "brain-teasers," assuming the same things that
the OP's code assumed (sign-propagation, two's-complement, 32-bit, no
trap on overflow...). But we didn't have to do absolute value for our
lab.)
In a clc sense, it doesn't work at all.

By "works," of course, I meant "produces correct results on my
implementation."

Well, that's not the clc sense of "works." :-)
(x < 0 ? -x : x)

Certainly would have been my first choice, but all conditional operators
were explicitly forbidden by the assignment. The 32-bit integer assumption
was explicitly permitted, and two's complement representation was
implied. Since the code was only required to work on a specific
implementation (an i386 Linux box, I believe), these assumptions were
acceptable in the context of the assignment.

Is this question impossible to answer in a strictly ANSI-compliant way,
then?

y = (x < 0)? -x: x;

This *is* the ISO-compliant way to compute absolute value. Bitwise
operators in C operate on bits, not values, so you can't use them to
compute [much of] anything related to value. C makes a distinction
between the *value* of an 'int' and the *representation* thereof.
<OT> I bet your code works [in the clc sense] in Java. </OT>

HTH,
-Arthur
Nov 13 '05 #10
Christopher Benson-Manica <at***@nospam.cyberspace.org> writes:
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

+ is not a bitwise operator.
--
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;}
Nov 13 '05 #11
that you might find interesting:

#include <stdio.h>
#include <limits.h>

/* Return X + 1. */
unsigned
uincr (unsigned x)
{
unsigned y;

for (y = 1; y != 0; y <<= 1)
if ((x ^= y) & y)
break;

return x;
}

/* Return X - 1. */
unsigned
udecr (unsigned x)
{
unsigned y;

for (y = 1; y != 0; y <<= 1)
if (!((x ^= y) & y))
break;

return x;
}

/* Returns value of most significant bit in unsigned type. */
unsigned
msb (void)
{
/* There must be a better way... */
unsigned y;
for (y = 1; y << 1; y <<= 1);
return y;
}

/* Negates X, which is in the machine's native int format. */
unsigned
negate (unsigned x)
{
if ((int) UINT_MAX == -1)
return uincr (~x);
else if ((int) UINT_MAX == 0)
return ~x;
else
return x ^ msb ();
}

/* Converts X, in the machine's native int format, to 2's complement
form. */
unsigned
n2twos (unsigned x)
{
if ((x & msb ()) == 0 || (int) UINT_MAX == -1)
return x;
else if ((int) UINT_MAX == 0)
return uincr (x);
else
return uincr (~(x ^ msb ()));
}

/* Converts X, in 2's complement format, to the machine's native int
format. */
int
twos2n (unsigned x)
{
if ((x & msb ()) == 0 || (int) UINT_MAX == -1)
return x;
else if ((int) UINT_MAX == 0)
return udecr (x);
else
return uincr (~x) ^ msb ();
}

/* Returns the bit pattern in X as an int. */
int
u2i (unsigned x)
{
return *(int *) &x;
}

/* Returns the bit pattern in X as an unsigned. */
unsigned
i2u (int x)
{
return *(unsigned *) &x;
}

/* Returns X + 1. */
int
sincr (int x)
{
return u2i (twos2n (uincr (n2twos (i2u (x)))));
}

/* Returns X - 1. */
int
sdecr (int x)
{
return u2i (twos2n (udecr (n2twos (i2u (x)))));
}

int
main (void)
{
int x;

for (x = -10; x <= +10; x = sincr (x))
printf ("% 3d ", x, negate (x));
putchar ('\n');

for (x = +10; x >= -10; x = sdecr (x))
printf ("% 3d ", x);
putchar ('\n');

return 0;
}

--
--Richard Heathfield
Nov 13 '05 #12

On Mon, 8 Sep 2003, Arthur J. O'Dwyer wrote:

On Mon, 8 Sep 2003, Christopher Benson-Manica wrote:
Peter Nilsson <ai***@acay.com.au> spoke thus:
Why?

It was an assignment for the intro-to-C class at school and I was
trying to help a friend... and it was a macho thing to prove I
could do it ;)

(BTW, I'm in a course this year whose first lab consists entirely of
about a dozen of these "brain-teasers," assuming the same things that
the OP's code assumed (sign-propagation, two's-complement, 32-bit, no
trap on overflow...). But we didn't have to do absolute value for our
lab.)

Funny story... right after I wrote that, I headed to recitation for
the systems class (15-213, for anyone who cares). And what should
we be doing in recitation but going over an example trick for the
lab -- namely, the "absolute value" one!

So I got to "show off" by putting the (x ^ x>>31) +1+~ (x>>31)
solution on the chalkboard off the top of my head. ;-)

-Arthur
Nov 13 '05 #13
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote in message news:<bj**********@chessie.cirr.com>...
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers. [...]
It also assumes twos complement arithmetic. I.e., -x = 1+~x is true
for twos complement, but not for example, in ones complement.
Unfortunately, the ANSI C standard does not specify whether or not you
can assume twos complement representations, so this whole idea is not
really useful in C.

Of course, it is highly unlikely you will ever encounter a non-twos
complement machine ever in your life (and ones complement has been
aggressively phased out pretty much everywhere), however the ANSI C
standard does not take this into account.
[...] Is there a portable/standard way to do this?
Syntactically or semantically? I mean, to be truly semantically
portable you have to build up your own twos complement model from
scratch. I suppose that's doable, but its also pure nonsense.
[...] Or are ANSI integers always 32 bits?
Not ANSI C, however Java integers are always 32 bits, and the
operators are always twos complement. So if you really really
need/want to perform this trick and you actually need to be portable,
you probably should switch to Java. ANSI C really doesn't have
anything to offer you.
[...] If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

Apparently bytes can be something other than 8 bits. I've seen people
post things like "CHAR_BITS" in this newsgroup, however, I don't know
whether that's part of any standard.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 13 '05 #14

"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote in message
news:bj*********@news7.svr.pol.co.uk...

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message

are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?
Integers can be 16, 32 or very rarely another number of bits. chars are
usually 8 bits but 9 or 32 has occasionally been reported.

using ( sizeof(int) * CHAR_BIT ) will be reasonably portable, but

vulnerable to padding bits. INT_MAX will give you the maximum value of an integer.
There is also no guarantee that your system uses two's complement
representation of negative numbers.

I would think that preprocessor expressions could separate twos complement,
ones complement, and sign magnitude.

#if ~0==-1
printf("twos complement\n");
#elif ~0==-0
printf("ones complement\n");
#else
printf("sign magnitude\n");
#endif

Then the three different bitwise absolute value expressions could be
conditionally generated

How about x&((~0>>1)) for sign magnitude?

-- glen
Nov 13 '05 #15

"Carsten Hansen" <ha******@worldnet.att.net> wrote in message
news:RB**********************@bgtnsc05-news.ops.worldnet.att.net...
Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code. It avoids a branch which is important on today's processors.
Be aware that Sun has a patent on this method.

Are you sure that works? It seems close but not right to me.

Conditional load is designed to avoid branch. Don't most machines have an
absolute value instruction?

-- glen
Nov 13 '05 #16
Glen Herrmannsfeldt wrote:
#if ~0==-1
printf("twos complement\n");
#elif ~0==-0
printf("ones complement\n");
#else
printf("sign magnitude\n");
#endif

Then the three different bitwise absolute value expressions could be
conditionally generated

How about x&((~0>>1)) for sign magnitude?

(~0) is not a portable expression.
Representations which would equate to (-0), may be traps.

--
pete
Nov 13 '05 #17

"Glen Herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote in message
news:yua7b.396502\$o%2.177909@sccrnsc02...

"Carsten Hansen" <ha******@worldnet.att.net> wrote in message
news:RB**********************@bgtnsc05-news.ops.worldnet.att.net...
Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code. It avoids a branch
which is
important on today's processors.
Be aware that Sun has a patent on this method.
Are you sure that works? It seems close but not right to me.

Either it works or it doesn't. Give an example where it fails.
Be aware that both Microsoft's and Intel's compiler generate the equivalent
code

value in eax
cdq
xor eax,edx
sub eax,edx

Also, the trick is mentioned in IBM's guide for compiler writers for the
PowerPC.
Conditional load is designed to avoid branch. Don't most machines have an
absolute value instruction?

-- glen

They may have an instruction for taking the absolute value of a
floating-point number. But neither the x86 nor the PowerPC have an
instruction for taking the absolute value of a fixed-point number.

Carsten Hansen

Nov 13 '05 #18
Christopher Benson-Manica wrote:
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers. Is there a portable/standard way
to do this? Or are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

Hmm. If you're going to allow arithmetic operators, then how about:

int my_abs(int x)
{ return x * ((x > 0) - (x < 0))
}

--
Morris Dovey
West Des Moines, Iowa USA

Nov 13 '05 #19
Morris Dovey wrote:

Christopher Benson-Manica wrote:
I'm trying to compute the absolute value of an integer using only bitwise
operators...

int x;
sscanf( "%d", &x );
printf( "%d\n", (x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers.
Is there a portable/standard way
to do this? Or are ANSI integers always 32 bits? If not, is using
sizeof(int) * 8 - 1 as the shift value an acceptable alternative?

Hmm. If you're going to allow arithmetic operators, then how about:

int my_abs(int x)
{ return x * ((x > 0) - (x < 0))
}

You also inserted relational operators.

--
pete
Nov 13 '05 #20
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote:
[...]
(x < 0 ? -x : x)

Certainly would have been my first choice, but all conditional operators were
explicitly forbidden by the assignment. The 32-bit integer assumption was
explicitly permitted, and two's complement represenation was implied. Since
the code was only required to work on a specific implementation (an i386 Linux
box, I believe), these assumptions were acceptable in the context of the
assignment.

Is this question impossible to answer in a strictly ANSI-compliant way, then?

Not at all:

x * (2 * (x > 0) - 1)

(Chances are this will result in a branch in the generated machine code
- but that's not what the question asked).

- Kevin.

Nov 13 '05 #21

"Carsten Hansen" <ha******@worldnet.att.net> wrote in message
news:Q_**********************@bgtnsc05-news.ops.worldnet.att.net...

(snip)
Why not just (x ^ (x>>31)) - (x>>31)?
Good compilers will actually generate this code.
It avoids a branch which is
important on today's processors.
Be aware that Sun has a patent on this method.
Are you sure that works? It seems close but not right to me.

Either it works or it doesn't. Give an example where it fails.
Be aware that both Microsoft's and Intel's compiler generate the

equivalent code

value in eax
cdq
xor eax,edx
sub eax,edx
Oh, arithmetic shift right. I was considering logical shift right. I would
have to get out my book, but I thought C didn't specify which one you got.
Also, the trick is mentioned in IBM's guide for compiler writers for the
PowerPC.
Won't that violate the previously mentioned Sun patent? (Maybe only if one
actually uses it?)
Conditional load is designed to avoid branch. Don't most machines have an absolute value instruction?

They may have an instruction for taking the absolute value of a
floating-point number. But neither the x86 nor the PowerPC have an
instruction for taking the absolute value of a fixed-point number.

The only architecture that I have coded one on, S/370, has it. Alpha, as
far as I can tell, uses a conditional load (between registers) to do it in
two instructions with no branch. I thought VAX did, but I don't see it in
the book, so I guess not.

-- glen
Nov 13 '05 #22
Paul Hsieh wrote:
... snip ...
Apparently bytes can be something other than 8 bits. I've seen
people post things like "CHAR_BITS" in this newsgroup, however,
I don't know whether that's part of any standard.

From N869:

5.2.4.2.1 Sizes of integer types <limits.h>

[#1] The values given below shall be replaced by constant
expressions suitable for use in #if preprocessing
directives. Moreover, except for CHAR_BIT and MB_LEN_MAX,
the following shall be replaced by expressions that have the
same type as would an expression that is an object of the
corresponding type converted according to the integer
promotions. Their implementation-defined values shall be
equal or greater in magnitude (absolute value) to those
shown, with the same sign.

-- number of bits for smallest object that is not a bit-
field (byte)
CHAR_BIT 8

--
Replies should be to the newsgroup
Chuck Falconer, on vacation.
Nov 13 '05 #23
pete wrote:

Glen Herrmannsfeldt wrote:
#if ~0==-1
printf("twos complement\n");
#elif ~0==-0
printf("ones complement\n");
#else
printf("sign magnitude\n");
#endif

Then the three different bitwise absolute value expressions could be
conditionally generated

How about x&((~0>>1)) for sign magnitude?

(~0) is not a portable expression.
Representations which would equate to (-0), may be traps.

#if !(1 & -1)
printf("ones complement\n");
#elif -1 & 2
printf("twos complement\n");
#else
printf("sign magnitude\n");
#endif

Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

--
pete
Nov 13 '05 #24

"pete" <pf*****@mindspring.com> wrote in message
news:3F***********@mindspring.com...
pete wrote:

Glen Herrmannsfeldt wrote:
#if ~0==-1
printf("twos complement\n");
#elif ~0==-0
printf("ones complement\n");
#else
printf("sign magnitude\n");
#endif

Then the three different bitwise absolute value expressions could be
conditionally generated

How about x&((~0>>1)) for sign magnitude?

(~0) is not a portable expression.
Representations which would equate to (-0), may be traps.

#if !(1 & -1)
printf("ones complement\n");
#elif -1 & 2
printf("twos complement\n");
#else
printf("sign magnitude\n");
#endif

Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Positive integers must have the traditional binary representation, but sign
magnitude is allowed for negative integers. I think that any definition of
sign magnitude would disallow a different representation of the magnitude
for positive and negative numbers.

-- glen
Nov 13 '05 #25
pete <pf*****@mindspring.com> writes:
Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Yes. Positive values have to be the ordinary binary
representation. Here is what C99 says about negative values:

If the sign bit is one, the value shall be
modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign
and magnitude);
- the sign bit has the value -(2N) (two's complement);
- the sign bit has the value -(2N - 1) (one's complement).

--
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;}
Nov 13 '05 #26
"Glen Herrmannsfeldt" <ga*@ugcs.caltech.edu> writes:
Oh, arithmetic shift right. I was considering logical shift right. I would
have to get out my book, but I thought C didn't specify which one you got.

It doesn't:

4 The result of E1 << E2 is E1 left-shifted E2 bit positions;
vacated bits are filled with zeros. If E1 has an unsigned
type, the value of the result is E1 Ã 2E2, reduced modulo
one more than the maximum value representable in the result
type. If E1 has a signed type and nonnegative value, and E1
Ã 2E2 is representable in the result type, then that is the
resulting value; otherwise, the behavior is undefined.

5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If
E1 has an unsigned type or if E1 has a signed type and a
nonnegative value, the value of the result is the integral
part of the quotient of E1 / 2E2. If E1 has a signed type
and a negative value, the resulting value is
implementation-defined.

(Note that some of those values should be superscripted.)
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton
Nov 13 '05 #27
Kevin Easton <kevin@-nospam-pcug.org.au> writes:
x * (2 * (x > 0) - 1)

(Chances are this will result in a branch in the generated machine code
- but that's not what the question asked).

It asked for use of only bitwise operators. Not only did you use
non-bitwise operators, you didn't use any bitwise operators at
all.
--
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;}
Nov 13 '05 #28
pete wrote:
pete wrote:
Glen Herrmannsfeldt wrote:
#if ~0==-1
printf("twos complement\n");
#elif ~0==-0
printf("ones complement\n");
#else
printf("sign magnitude\n");
#endif

Then the three different bitwise absolute value expressions could be
conditionally generated

How about x&((~0>>1)) for sign magnitude?

(~0) is not a portable expression.
Representations which would equate to (-0), may be traps.

#if !(1 & -1)
printf("ones complement\n");
#elif -1 & 2
printf("twos complement\n");
#else
printf("sign magnitude\n");
#endif

Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Yes. There is something about binary bit weights somewhere.

--
Replies should be to the newsgroup
Chuck Falconer, on vacation.
Nov 13 '05 #29
pete wrote:
Morris Dovey wrote:
Christopher Benson-Manica wrote:
I'm trying to compute the absolute value of an integer
using only bitwise operators...

int x; sscanf( "%d", &x ); printf( "%d\n",
(x^((~((x>>31)&1))+1)) + ((x>>31)&1) );

That works, but it assumes 32 bit integers. Is there a
portable/standard way to do this? Or are ANSI integers
always 32 bits? If not, is using sizeof(int) * 8 - 1 as
the shift value an acceptable alternative?

Hmm. If you're going to allow arithmetic operators, then how

int my_abs(int x) { return x * ((x > 0) - (x < 0)) }

You also inserted relational operators.

I did, didn't I?

Good catch. 8^)
--
Morris Dovey
West Des Moines, Iowa USA

Nov 13 '05 #30
Ben Pfaff wrote:

pete <pf*****@mindspring.com> writes:
Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Yes. Positive values have to be the ordinary binary
representation. Here is what C99 says about negative values:

If the sign bit is one, the value shall be
modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign
and magnitude);
- the sign bit has the value -(2N) (two's complement);
- the sign bit has the value -(2N - 1) (one's complement).

Thank you.

--
pete
Nov 13 '05 #31
Ben Pfaff <bl*@cs.stanford.edu> wrote:
Kevin Easton <kevin@-nospam-pcug.org.au> writes:
x * (2 * (x > 0) - 1)

(Chances are this will result in a branch in the generated machine code
- but that's not what the question asked).

It asked for use of only bitwise operators. Not only did you use
non-bitwise operators, you didn't use any bitwise operators at
all.

The example given in the original question used addition operators. I
can add a shift operator if you like:

x * (((x > 0) << 1) - 1)

or

x + x * ((x < 0) << 1)

- Kevin.
Nov 13 '05 #32
In <87************@pfaff.stanford.edu> Ben Pfaff <bl*@cs.stanford.edu> writes:
pete <pf*****@mindspring.com> writes:
Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Yes. Positive values have to be the ordinary binary
representation. Here is what C99 says about negative values:

If the sign bit is one, the value shall be
modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign
and magnitude);
- the sign bit has the value -(2N) (two's complement);
- the sign bit has the value -(2N - 1) (one's complement).

Nope, this is definitely NOT what C99 says about negative values.
The last two lines are properly rendered in plain text as:

- the sign bit has the value -(2**N) (two's complement);
- the sign bit has the value -(2**N - 1) (one's complement).

Where ** stands for the exponentiation operator. The mechanical
translation from PDF to plain text doesn't work as well as some people
naively believe...

But this text is completely missing from C89, which is the currently
implemented standard, so there is nothing preventing a current
implementation from adopting Pete's model for representing negative
values. In theory, at least ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #33
Da*****@cern.ch (Dan Pop) writes:
In <87************@pfaff.stanford.edu> Ben Pfaff <bl*@cs.stanford.edu> writes:
pete <pf*****@mindspring.com> writes:
Is there any wording in the standard which prohibits
negative integer values from being represented by
the sign bit and a gray code representation of the magnitude ?

Yes. Positive values have to be the ordinary binary
representation. Here is what C99 says about negative values:

If the sign bit is one, the value shall be
modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign
and magnitude);
- the sign bit has the value -(2N) (two's complement);
- the sign bit has the value -(2N - 1) (one's complement).

Nope, this is definitely NOT what C99 says about negative values.
The last two lines are properly rendered in plain text as:

- the sign bit has the value -(2**N) (two's complement);
- the sign bit has the value -(2**N - 1) (one's complement).

Of course. That's obvious.
--
Just another C hacker.
Nov 13 '05 #34
In <87************@pfaff.stanford.edu> Ben Pfaff <bl*@cs.stanford.edu> writes:
Da*****@cern.ch (Dan Pop) writes:
In <87************@pfaff.stanford.edu> Ben Pfaff <bl*@cs.stanford.edu> writes:
>pete <pf*****@mindspring.com> writes:
>
>> Is there any wording in the standard which prohibits
>> negative integer values from being represented by
>> the sign bit and a gray code representation of the magnitude ?
>
>Yes. Positive values have to be the ordinary binary
>representation. Here is what C99 says about negative values:
>
> If the sign bit is one, the value shall be
> modified in one of the following ways:
> - the corresponding value with sign bit 0 is negated (sign
> and magnitude);
> - the sign bit has the value -(2N) (two's complement);
> - the sign bit has the value -(2N - 1) (one's complement).

Nope, this is definitely NOT what C99 says about negative values.
The last two lines are properly rendered in plain text as:

- the sign bit has the value -(2**N) (two's complement);
- the sign bit has the value -(2**N - 1) (one's complement).

Of course. That's obvious.

If you're already familiar with the issue, yes. Otherwise, 2N is supposed
to be read as 2 * N and not as 2 ** N.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #35

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

 4 posts views Thread by Mike Hodkin | last post: by 6 posts views Thread by jas_lx | last post: by 9 posts views Thread by Christopher Weaver | last post: by 37 posts views Thread by James Radke | last post: by 3 posts views Thread by shdwsclan | last post: by 5 posts views Thread by noridotjabi | last post: by 17 posts views Thread by zirconx | last post: by 3 posts views Thread by Jay Ruyle | last post: by 45 posts views Thread by Carramba | last post: by reply views Thread by billypeterson | last post: by reply views Thread by strativab | last post: by reply views Thread by gheharukoh7 | last post: by reply views Thread by tieutu2004 | last post: by 2 posts views Thread by JamesNapier | last post: by reply views Thread by isladogs | last post: by reply views Thread by isladogs | last post: by 1 post views Thread by jerryg72 | last post: by reply views Thread by MoonNbl | last post: by