G
Guest
I'm guessing you had to use multiply or divide if you actually needed
to
shift bits
[...]Jujitsu Lizard said:The other posters in this newsgroup are knuckleheads who don't
understand C, computing in general, or digital logic design. Let me
help you out here.
I did not realize that sign-magnitude representation was legal on a machine
with a C compiler (why would any sane person represent integers that way?).
pete said:Jujitsu said:blargg said::
[...]
As far as the right-shift operator applied to negative numbers,
you'll find
that every compiler known to man either propagates the sign bit into the
leftmost position or else uses 0's (depending on the machine
instructions
chosen). Usually the only unknown is the "fill".
You can get around this if you really need to.
Need to shift a signed number right 5 bits?
if (x<0)
{
result = (x >> 5) | (-1 << (sizeof(int) * 8 - 5);
}
else
{
result = ((unsigned)(x)) >> 5;
}
The above code seems questionable (assumes char is 8 bits, two's
complement where it ORs -1 shifted?, and the unsigned cast at the end is
unnecessary). How about this? (the conversion to unsigned before negation
is to properly handle the most negative value of a signed int on a two's
complement machine)
(x < 0) ? -(int) (-(unsigned) x >> 5) : (x >> 5)
My intent was to bypass the ambiguous handling of the sign
propagation on right shift by masking in bits as if the sign bit had
propagated. In other words, the code I posted was designed to
generate code that would effectively always propagate the sign bit
on right shift.
if (0 > x) {
x = -x;
I did not realize that sign-magnitude representation was legal on a machine
with a C compiler (why would any sane person represent integers that way?).
I thought that shifting a signed integer to the left was perfectly
defined but shifting a signed integer to the right had the bothersome
complexity.
Am I wrong?
blargg said:.... snip ...
BTW, in another message in this thread someone said that shifting
a signed value right is undefined. My copy of the C99 standard
says otherwise:
blargg said:Sorry if I'm repeating myself from another message (or forgot the
reason given), but couldn't a compiler on a two's complement
platform do the same thing, define INT_MIN to be -INT_MAX? For
example, if int is 16 bits on such a machine, then INT_MAX would
be 32767 and INT_MIN would be -32767. Then you're guaranteed that
every valid value of an int can be negated properly.
pete said:Jujitsu Lizard wrote:
.... snip ...
if (0 > x) {
x = -x;
x >>= 5;
x = -x;
}
Jujitsu Lizard said:I did not realize that sign-magnitude representation was legal on a machine
with a C compiler (why would any sane person represent integers that way?).
blargg said:jameskuyper wrote: ....
Sorry if I'm repeating myself from another message (or forgot the reason
given), but couldn't a compiler on a two's complement platform do the same
thing, define INT_MIN to be -INT_MAX? For example, if int is 16 bits on
such a machine, then INT_MAX would be 32767 and INT_MIN would be -32767.
Then you're guaranteed that every valid value of an int can be negated
properly.
CBFalconer said:Your quote (repeated above) specifies implementation-defined. This
also means that you don't know what your code will do on another
compiler or system.
jameskuyper said:You're confusing "implementation-defined value" with "undefined
behavior", which is precisely the distinction he's making. If the
behavior were undefined, as was incorrectly claimed, it would indeed
be the case that "you don't know what your code will do on another
machine", and the implemenation for that other machine has no
obligation to document what that behavior will be.
Since the behavior is in fact implementation-defined, you know that
such code will produce a valid value of the specified type, no matter
which conforming implementation you use. If your code makes no
assumptions about which valid value that is, it will still work (for
instance, it could print out what that value is). You also know that
you can find out what the value will be by reading the
implementation's documentation.
And then, on such a machine, you have an illegal bit pattern for an
integer left over. No other languages or programs on that machine
understand this. What are you going to do with it?
jameskuyper said:CBFalconer wrote:
.... snip ...
You're confusing "implementation-defined value" with "undefined
behavior", which is precisely the distinction he's making. If the
behavior were undefined, as was incorrectly claimed, it would
indeed be the case that "you don't know what your code will do on
another machine", and the implemenation for that other machine
has no obligation to document what that behavior will be.
Flash said:I think the standards committee disagreed with you since they
explicitly allow what you are denigrating. In any case, how do you
know the no other languages would understand it? The most likely
time it would occur is on a processor which would/could trap on it
(or possibly do a hard limit on arithmetic at +/-32767. There are
even good reasons for this behaviour to be desired in signal
processing.
CBFalconer said:No, I'm not. You have no a-priori knowledge of what that 'other
system' consists, thus you don't know what your code will do.
Implementation-defined is only better than undefined when you are
writing code for exactly one known system, which is adequately
documented. If so, your queries don't belong on c.l.c.
CBFalconer said:No, I'm not. You have no a-priori knowledge of what that 'other
system' consists, thus you don't know what your code will do.
Implementation-defined is only better than undefined when you are
writing code for exactly one known system, which is adequately
documented.
If so, your queries don't belong on c.l.c.
For example, this program:
#include <stdio.h>
int main(void) {
printf("Your system thinks -10 >> 2 == %d. Isn't that nice?\n",
-10 >> 2);
return 0;
}
may print
By contrast, this program:
#include <stdio.h>
int main(void) {
printf("Your system thinks -10 >> 2 == %d. Isn't that nice?\n",
-10 >> 2);
return 0;
}
Ben Bacarisse said:There is no contrast! Presumably you meant -10 << 2 in the second case.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.