octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bitshift of int8, int16, etc?


From: Daniel J Sebald
Subject: Re: bitshift of int8, int16, etc?
Date: Mon, 25 Jun 2007 10:59:19 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20041020

David Bateman wrote:
Daniel J Sebald wrote:


which to me seems to be the right behavior for an arithmetic shift
operator..

Alright.  What I suggested was an implementation in which the sign
bit did not participate in the bit shift either left or right.  To
be technical, the


% ./temp -1 -1
-1

is for two's complement behavior.  One's complement would round to
zero if I understand some documentation on the web.  (Supposedly C
doesn't call out a behavior for right shifting negative numbers,
and leaves that up to the compiler to call out.)


Wouldn't ones-complement representation of "-1" right-shifted by 1 bit
turn into "64" for a logical shift and "-64" for an arithmetic shift?

It's been years...

00000001 11111110 (one's complement)
11111100  (right shift)
00000011  (going back)

... I don't think so.  Looks like -3.


The C standard doesn't define the behavior of the right shift of
negative numbers as it is supposed to work on architectures with both
ones and twos complement representation. However, aren't all integer
types on modern architectures are twos complements and so the right
shift operator should be similar. The only question is whether the
compiler chooses an arithmetic or logical shift for negative numbers.

I suppose the best to make sure that Octave is consistent across
compilers is to avoid the issue and operator always of positive numbers.
A means that would be consistent with Matlab's floating point version of
the bitshift operator would be to do something like

template <class T2>
octave_int<T>& operator >>= (const T2& x)
{
  if (ival < 0)
    ival = - (((-ival) >> x) & std::numeric_limits<T>::max());
  else
    ival = ival >> x;
  return *this;
}
[snip]
This will cause a few compile warnings for the unsigned types though as
for the unsigned types (ival < 0) is always false.. It would however
enforce a strict two complements arithmetic shift operator regardless of
the compilers implementation of shifts of negative numbers.

That's another interesting way of looking at it.  Basically undoing the 
inherent complementation?


In any case, there probably should be a record kept of an overflow.
These two are examples:


%. /temp 64 1
-128
% ./temp 127 1
-2

Anyone working with those numbers who doesn't have access to info
about overflow might be in a bind.



Ok, I'm unsure what's the best solution, but still think the case of
"bitshift(127,1)" should return -2....

A global flag that the user can retrieve somehow?  Maybe something like

overflow = (ival < 0);
(shift)
overflow ^= (ival < 0);

I'm not sure how one would retrieve 'overflow', however.  Otherwise, leave it 
up to the user to implement the check (but making it part of the language 
promotes consistency).

Dan


reply via email to

[Prev in Thread] Current Thread [Next in Thread]