changeset 4920:b22a7a1db0d5

[project @ 2004-07-27 18:15:25 by jwe]
author jwe
date Tue, 27 Jul 2004 18:16:18 +0000
parents a1073eef650c
children d0b8964b9d4b
files liboctave/ChangeLog liboctave/oct-inttypes.h scripts/general/bitcmp.m scripts/general/bitget.m scripts/general/bitset.m src/ChangeLog src/bitfcns.cc
diffstat 7 files changed, 89 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/ChangeLog	Tue Jul 27 15:22:51 2004 +0000
+++ b/liboctave/ChangeLog	Tue Jul 27 18:16:18 2004 +0000
@@ -1,3 +1,8 @@
+2004-07-27  John W. Eaton  <jwe@octave.org>
+
+	* oct-inttypes.h (bitshift): New arg, MASK.
+	(OCTAVE_INT_BITSHIFT_OP): Bitshift does not saturate.
+
 2004-07-23  John W. Eaton  <jwe@octave.org>
 
 	* Array.cc (Array<T>::reshape): Return *this if no change in size.
--- a/liboctave/oct-inttypes.h	Tue Jul 27 15:22:51 2004 +0000
+++ b/liboctave/oct-inttypes.h	Tue Jul 27 18:16:18 2004 +0000
@@ -279,7 +279,7 @@
   octave_int<T1> \
   operator OP (const octave_int<T1>& x, const T2& y) \
   { \
-    return x.value () OP y; \
+    return ((x.value () OP y) > std::numeric_limits<T1>::max ()) ? 0 : (x.value () OP y); \
   }
 
 OCTAVE_INT_BITSHIFT_OP (<<)
@@ -287,12 +287,13 @@
 
 template <class T>
 octave_int<T>
-bitshift (const octave_int<T>& a, int n)
+bitshift (const octave_int<T>& a, int n,
+	  const octave_int<T>& mask = std::numeric_limits<T>::max ())
 {
   if (n > 0)
-    return a << n;
+    return (a.value () << n) & mask.value ();
   else if (n < 0)
-    return a >> -n;
+    return (a.value () >> -n) & mask.value ();
   else
     return a;
 }
--- a/scripts/general/bitcmp.m	Tue Jul 27 15:22:51 2004 +0000
+++ b/scripts/general/bitcmp.m	Tue Jul 27 18:16:18 2004 +0000
@@ -16,7 +16,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{X} =} bitcmp (@var{a},@var{k})
-## returns the @var{k}-bit complement of integers in @var{a}. If
+## Return the @var{k}-bit complement of integers in @var{a}.  If
 ## @var{k} is omitted @code{k = log2(bitmax) + 1} is assumed.
 ##
 ## @example
@@ -36,30 +36,30 @@
 function X = bitcmp (A, n)
   
   if (nargin < 1 || nargin > 2)
-    usage ("bitcmp(A,n)");
+    usage ("bitcmp (A, n)");
   endif
 
-  cname = class(A);
+  cname = class (A);
   if (strcmp (cname, "double"))
     Bmax = bitmax;
     Amax = log2 (Bmax) + 1;
-  elseif strcmp("uint",substr(cname,1,4))
-    Bmax = intmax(cname);
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 1);"]);
+  elseif strcmp ("uint", substr (cname, 1, 4))
+    Bmax = intmax (cname);
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 1);"]);
   else
-    Bmax = eval([cname, " (-1);"]);
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 2);"]);
+    Bmax = eval ([cname, " (-1);"]);
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 2);"]);
   endif
 
-  Aone = eval([ cname, "(1);"]);
+  Aone = eval ([ cname, "(1);"]);
   if (nargin == 2)
-    m = eval([cname, " (n(:));"]);
-    if (any(m < Aone) || any( m > Amax))
+    m = eval ([cname, " (n(:));"]);
+    if (any (m < Aone) || any (m > Amax))
       error ("n must be in the range [1,%d]", Amax);
     endif
-    X = bitxor(A, bitshift(Bmax, -n));
+    X = bitxor (A, bitshift (Bmax, -n));
   else
-    X = bitxor(A, Bmax);
+    X = bitxor (A, Bmax);
   endif
 
 endfunction
--- a/scripts/general/bitget.m	Tue Jul 27 15:22:51 2004 +0000
+++ b/scripts/general/bitget.m	Tue Jul 27 18:16:18 2004 +0000
@@ -16,35 +16,36 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{X} =} bitget (@var{a},@var{n})
-## returns the status of bit(s) @var{n} of unsigned integers in @var{a}
+## Return the status of bit(s) @var{n} of unsigned integers in @var{a}
 ## the lowest significant bit is @var{n} = 1.
 ##
 ## @example
-## bitget(100,8:-1:1)
+## bitget (100, 8:-1:1)
 ## @result{} 0  1  1  0  0  1  0  0 
 ## @end example
-## @seealso{bitand,bitor,bitxor,bitset,bitcmp,bitshift,bitmax}
+## @seealso{bitand, bitor, bitxor, bitset, bitcmp, bitshift, bitmax}
 ## @end deftypefn
 
 ## Liberally based of the version by Kai Habel from octave-forge
 
 function X = bitget (A, n)
+
   if (nargin != 2)
-    usage ("bitget(A,n)");
+    usage ("bitget (A, n)");
   endif
 
-  cname = class(A);
+  cname = class (A);
   if (strcmp (cname, "double"))
     Amax = log2 (bitmax) + 1;
-  elseif strcmp("uint",substr(cname,1,4))
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 1);"]);
+  elseif strcmp ("uint", substr (cname, 1, 4))
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 1);"]);
   else
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 2);"]);
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 2);"]);
   endif
 
-  Aone = eval([ cname, "(1);"]);
-  m = eval([cname, " (n(:));"]);
-  if (any(m < Aone) || any( m > Amax))
+  Aone = eval ([ cname, "(1);"]);
+  m = eval ([cname, " (n(:));"]);
+  if (any (m < Aone) || any (m > Amax))
     error ("n must be in the range [1,%d]", Amax);
   endif
 
--- a/scripts/general/bitset.m	Tue Jul 27 15:22:51 2004 +0000
+++ b/scripts/general/bitset.m	Tue Jul 27 18:16:18 2004 +0000
@@ -15,23 +15,24 @@
 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{X} =} bitset (@var{a},@var{n})
-## @deftypefnx {Function File} {@var{X} =} bitset (@var{a},@var{n},@var{v})
-## sets or resets bit(s) @var{N} of unsigned integers in @var{A}.
+## @deftypefn {Function File} {@var{x} =} bitset (@var{a}, @var{n})
+## @deftypefnx {Function File} {@var{x} =} bitset (@var{a}, @var{n}, @var{v})
+## Set or reset bit(s) @var{n} of unsigned integers in @var{a}.
 ## @var{v} = 0 resets and @var{v} = 1 sets the bits.
 ## The lowest significant bit is: @var{n} = 1
 ##
 ## @example
-## dec2bin (bitset(10,1))
+## dec2bin (bitset (10, 1))
 ## @result{} 1011
 ## @end example
 ##
-## @seealso{bitand,bitor,bitxor,bitget,bitcmp,bitshift,bitmax}
+## @seealso{bitand, bitor, bitxor, bitget, bitcmp, bitshift, bitmax}
 ## @end deftypefn
 
 ## Liberally based of the version by Kai Habel from octave-forge
 
 function X = bitset (A, n, value)
+
   if (nargin < 2 || nargin > 3)
     usage ("bitset (A, n, v)");
   endif
@@ -40,21 +41,21 @@
     value = 1;
   endif
   
-  cname = class(A);
+  cname = class (A);
   if (strcmp (cname, "double"))
     Bmax = bitmax;
     Amax = log2 (Bmax) + 1;
-  elseif strcmp("uint",substr(cname,1,4))
-    Bmax = intmax(cname);
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 1);"]);
+  elseif strcmp("uint", substr (cname, 1, 4))
+    Bmax = intmax (cname);
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 1);"]);
   else
-    Bmax = eval([cname, " (-1);"]);
-    Amax = eval([cname, " (log2 (double (intmax (cname))) + 2);"]);
+    Bmax = eval ([cname, " (-1);"]);
+    Amax = eval ([cname, " (log2 (double (intmax (cname))) + 2);"]);
   endif
 
-  Aone = eval([ cname, "(1);"]);
-  m = eval([cname, " (n(:));"]);
-  if (any(m < Aone) || any( m > Amax))
+  Aone = eval ([ cname, "(1);"]);
+  m = eval ([cname, " (n(:));"]);
+  if (any (m < Aone) || any (m > Amax))
     error ("n must be in the range [1,%d]", Amax);
   endif
 
--- a/src/ChangeLog	Tue Jul 27 15:22:51 2004 +0000
+++ b/src/ChangeLog	Tue Jul 27 18:16:18 2004 +0000
@@ -1,5 +1,10 @@
 2004-07-27  John W. Eaton  <jwe@octave.org>
 
+	* bitfcns.cc (DO_BITSHIFT): Pass mask to bitshift.
+	(bitshift (double, int, EIGHT_BYTE_INT): New arg, mask.
+	(DO_UBITSHIFT, DO_SBITSHIFT): Use bitshfit, not operator >>.
+	Use nbits function from octave_int type to set bits_in_type.
+
 	* ov-struct.cc (Fisfield): Only print usage message if number of
 	arguments is incorrect.  Return false for invalid arguments.
 	From Andy Adler <adler@site.uottawa.ca>.
--- a/src/bitfcns.cc	Tue Jul 27 15:22:51 2004 +0000
+++ b/src/bitfcns.cc	Tue Jul 27 18:16:18 2004 +0000
@@ -265,7 +265,7 @@
 DEFUN (bitand, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} bitand (@var{x}, @var{y})\n\
-calculates the bitwise AND of nonnegative integers.\n\
+Return the bitwise AND of nonnegative integers.\n\
 @var{x}, @var{y} must be in range [0..bitmax]\n\
 @end deftypefn\n\
 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}")
@@ -276,7 +276,7 @@
 DEFUN (bitor, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} bitor (@var{x}, @var{y})\n\
-calculates the bitwise OR of nonnegative integers.\n\
+Return the bitwise OR of nonnegative integers.\n\
 @var{x}, @var{y} must be in range [0..bitmax]\n\
 @end deftypefn\n\
 @seealso{bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}")
@@ -287,7 +287,7 @@
 DEFUN (bitxor, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} bitxor (@var{x}, @var{y})\n\
-calculates the bitwise XOR of nonnegative integers.\n\
+Return the bitwise XOR of nonnegative integers.\n\
 @var{x}, @var{y} must be in range [0..bitmax]\n\
 @end deftypefn\n\
 @seealso{bitand, bitor, bitset, bitget, bitcmp, bitshift, bitmax}")
@@ -296,14 +296,14 @@
 }
 
 static EIGHT_BYTE_INT
-bitshift (const double& a, int n)
+bitshift (double a, int n, EIGHT_BYTE_INT mask)
 {
   if (n > 0)
-    return static_cast<EIGHT_BYTE_INT> (a) << n;
+    return (static_cast<EIGHT_BYTE_INT> (a) << n) & mask;
   else if (n < 0)
-    return static_cast<EIGHT_BYTE_INT> (a) >> -n;
+    return (static_cast<EIGHT_BYTE_INT> (a) >> -n) & mask;
   else
-    return static_cast<EIGHT_BYTE_INT> (a);
+    return static_cast<EIGHT_BYTE_INT> (a) & mask;
 }
 
 // Note that the bitshift operators are undefined if shifted by more
@@ -342,12 +342,12 @@
 		    if (static_cast<int> (n(k)) >= bits_in_type) \
 		      result(i+k) = 0; \
 		    else \
-		      result(i+k) = bitshift (m(i), static_cast<int> (n(k))) & mask; \
+		      result(i+k) = bitshift (m(i), static_cast<int> (n(k)), mask); \
 		else \
 		  if (static_cast<int> (n(i)) >= bits_in_type) \
 		    result(i) = 0;					\
 		  else 						\
-		    result(i) = bitshift (m(i), static_cast<int> (n(i))) & mask; \
+		    result(i) = bitshift (m(i), static_cast<int> (n(i)), mask); \
  \
 	      retval = result; \
 	    } \
@@ -361,11 +361,11 @@
 #define DO_UBITSHIFT(T, N) \
   do \
     { \
-      int bits_in_type = sizeof (octave_ ## T) << 3; \
+      int bits_in_type = octave_ ## T :: nbits (); \
       T ## NDArray m = m_arg.T ## _array_value (); \
 	octave_ ## T mask = ~0ULL; \
-      if ((N) < static_cast<int> (sizeof (octave_ ## T) << 3)) \
-	mask = mask >> ((sizeof (octave_ ## T) << 3) - (N)); \
+      if ((N) < bits_in_type) \
+	mask = bitshift (mask, (N) - bits_in_type); \
       else if ((N) < 1) \
 	mask = 0; \
       DO_BITSHIFT (T); \
@@ -375,11 +375,11 @@
 #define DO_SBITSHIFT(T, N) \
   do \
     { \
-      int bits_in_type = sizeof (octave_ ## T) << 3; \
+      int bits_in_type = octave_ ## T :: nbits (); \
       T ## NDArray m = m_arg.T ## _array_value (); \
 	octave_ ## T mask = -1; \
-      if ((N) < static_cast<int>(sizeof (octave_ ## T) << 3)) \
-	mask = mask >> ((sizeof (octave_ ## T) << 3) - (N)); \
+      if ((N) < bits_in_type) \
+	mask = bitshift (mask, (N) - bits_in_type); \
       else if ((N) < 1) \
 	mask = 0; \
       DO_BITSHIFT (T); \
@@ -390,10 +390,10 @@
   "-*- texinfo -*-\n\
 @deftypefn {Function File} {} bitshift (@var{a}, @var{k})\n\
 @deftypefnx {Function File} {} bitshift (@var{a}, @var{k}, @var{n})\n\
-return a @var{k} bit shift of @var{n}- digit unsigned\n\
-integers in @var{a}. A positive @var{k} leads to a left shift.\n\
-A negative value to a right shift. If @var{n} is omitted it defaults\n\
-to log2(bitmax)+1. \n\
+Return a @var{k} bit shift of @var{n}- digit unsigned\n\
+integers in @var{a}.  A positive @var{k} leads to a left shift.\n\
+A negative value to a right shift.  If @var{n} is omitted it defaults\n\
+to log2(bitmax)+1.\n\
 @var{n} must be in range [1,log2(bitmax)+1] usually [1,33]\n\
 \n\
 @example\n\
@@ -420,15 +420,23 @@
 
   if (nargin == 2 || nargin == 3)
     {
-      NDArray n = args(1).array_value ();
       int nbits = 64;
       
-      if (nargin == 3)
+      NDArray n = args(1).array_value ();
+
+      if (error_state)
+	error ("bitshift: expecting integer as second argument");
+      else
 	{
-	  nbits = args(2).nint_value ();
+	  if (nargin == 3)
+	    {
+	      nbits = args(2).int_value ();
 	  
-	  if (nbits < 0)
-	    error ("bitshift: number of bits to mask must be positive");
+	      if (error_state)
+		error ("bitshift: expecting integer as third argument");
+	      else if (nbits < 0)
+		error ("bitshift: number of bits to mask must be positive");
+	    }
 	}
 
       if (error_state)
@@ -477,8 +485,8 @@
 DEFUN (bitmax, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} bitmax ()\n\
-Returns the largest integer that can be represented as a floating point\n\
-value. That is for IEEE-754 compatiable systems with @code{2^53 - 1}.\n\
+Return the largest integer that can be represented as a floating point\n\
+value.  On IEEE-754 compatiable systems, @code{bitmax} is @code{2^53 - 1}.\n\
 @end deftypefn")
 {
   octave_value retval;