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 | 34 16756
"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.
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
"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
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 |
"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
the cases. Very bad.
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
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
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 |
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?
(reply snipped)
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 |
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 ;)
Yes, it is September already.
(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?
See Peter's answer.
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
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;}
It doesn't answer your question directly, but here's some code
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;
}
--
"Your correction is 100% correct and 0% helpful. Well done!"
--Richard Heathfield
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 ;)
Yes, it is September already. (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
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/
"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
"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
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
"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
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
C links at http://www.iedu.com/c
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
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.
"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
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.
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
"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
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;}
"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
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;}
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.
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 about:
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
C links at http://www.iedu.com/c
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
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.
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 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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Mike Hodkin |
last post by:
As a beginning student of C++, books reference "bitwise operators" and give
brief examples, but I have not read a good explanation of what they are used
for. One reference mentioned that they are...
|
by: jas_lx |
last post by:
The basic understanding of what bitwise operators (& ^ | >> << ) comes
fairly simple, as long as one has a fundamental understanding of bits,
bytes and binary.
Having done some Win32...
|
by: Christopher Weaver |
last post by:
I know that the bitwise AND of 8 and 4 will return 0 or false and the
bitwise AND of 8 and 9 will return 1 or true but I don't know how to write
the synax for it in C#. I have a value that ranges...
|
by: James Radke |
last post by:
Hello,
I found some code that I could use in my application on the web, but it is
written in C#, and I would like to convert it to VB. And I am having
problems with one section. Is there...
|
by: shdwsclan |
last post by:
I am native to various languages but bitwise operators just kill me. I see how much I take object oriented languages for granted. I like all the other c derivitives but ANSI C is making me loose my...
|
by: noridotjabi |
last post by:
I'm learning to program in C and any tutorial or book that I read likes
to briefly touch on birdies operators and then move on without giving
any sort of example application of them. Call me what...
|
by: zirconx |
last post by:
I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they...
|
by: Jay Ruyle |
last post by:
I'm trying to figure out a way to list several items in a listbox and let
the user select any number of items in the listbox. I have tried to code in
the items as bitwise items but all it stores...
|
by: Carramba |
last post by:
Hi!
I now that I can't do straight forward any bitwise operation on float
(double etc..). But I wondering what is the easiest/best way to do this?
I was thinking if I have float x=1.1111 so I can...
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: giovanniandrean |
last post by:
The energy model is structured as follows and uses excel sheets to give input data:
1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
|
by: NeoPa |
last post by:
Hello everyone.
I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report).
I know it can be done by selecting :...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
| |