-
Notifications
You must be signed in to change notification settings - Fork 561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
shifting of bitvecs considered broken #164
Comments
From @jhiResubmitting a bug report of mine back from February; [paste] While editing my Damn Book I re-remembered that couple of months back Fiction: you have a bitvector which you want to shift. The current (5.005_03-MT5) fact: perl -wle '$b = ""; vec($b, 0, 1) = 1;print unpack("b*", $b);$b<<=1;print unpack("b*", $b)' Huh? Adding -w tells more, as usual: So left_shift assumes that the argument to shift is a number, but "^A" I consider this behaviour to be rather broken. I think $b <<= 1 should shift the whole bitvector left by one position and vec($b, 2, 8) >>= 2 should shift the bits 16..23 right by two positions (of course not Back then I asked Larry whether the current behaviour is by design or larry: I suppose << and >> ought to be made to work. There's a little more P.S. My original problem can be recoded with "use integer", but the -- Perl Info
|
From @floatingatollI can confirm this is present in @18374. |
From @schwernStill present in 5.8.5 and blead@22511 |
From @smpeters
Just so we're clear, and to add a proper TODO test case, what would you |
From @iabynOn Wed, Jul 20, 2005 at 05:56:12AM -0700, Steve Peters via RT wrote:
I am opposed to such a change in behaviour. <<= operates on numeric values, while vec operates on strings. vec($b,0,1) = 1 is just the same as $b = "\x0\x0\x0\x01" (ignoring endianess and int size complications) If the << and >> operators were to take any string as a bit pattern, then $b="1"; $b <<= 2; print $b which should print 4, not "\xc4". -- |
From @jhi
Rest peacefully, so is Larry, I once cornered him on this :-)
But on the other hand Larry could see the argumentation my way too, How to solve this, if this is to be solved? *I* see as an ugly -- |
From @jhi
How is the fixing of lexical pragmas progressing? If there were -- |
From @rgarciaOn 8/6/05, Jarkko Hietaniemi <jhietaniemi@gmail.com> wrote:
I've an unfinished patch, and I've planned to work on this after the |
From @smpeters
This thread sort of went off on a tangent. What should the expected |
From @jhiSteve Peters via RT wrote:
Well, ASSUMING that there will be in future a way to make shifting of perl -Mbitvec -wle '$b = ""; -- |
From @ysthOn Wed, Sep 28, 2005 at 09:01:12AM +0300, Jarkko Hietaniemi wrote:
I'd rather see a pragma that allowed changing how &,|, etc. work also. to allow shifting as bitvecs if they've never been used in numeric context use bitvec string => -shiftops; to have the shift ops always shift as bitvecs, and use bitvec numeric => -shiftops; being the default, making the ops always assume numbers. It would also allow affecting the bitwise ops (~, &, |, ^) which use bitvec auto => -bitwise; And would restore the defaults. I know I'd use use bitvec string => -all; often in limited lexical scopes. |
From @chipdudeHow about adding leftshift() and rightshift() as functions in a standard |
From [Unknown Contact. See original ticket]How about adding leftshift() and rightshift() as functions in a standard |
From @rgs2008/11/14 Chip Salzenberg via RT <perlbug-comment@perl.org>:
Except the obligatory bikeshedding session on the new module name, |
From @chipdudeOn Mon, Nov 17, 2008 at 09:36:07AM +0100, Rafael Garcia-Suarez wrote:
I'm having a hard time deciding which way is "left". The convention for |
From @chipdudeOn Mon, Nov 17, 2008 at 09:36:07AM +0100, Rafael Garcia-Suarez wrote:
Well ... does it count as bikeshedding if it's your own module? Here's a =item insert_low_bits STRING, COUNT Accept a bitvector STRING, a la L<vec>, and an integral bit COUNT. Return a =item remove_low_bits STRING, COUNT Accept a bitvector STRING, a la L<vec>, and an integral bit COUNT. Return a Inline Patchdiff --git a/ext/vec/Makefile.PL b/ext/vec/Makefile.PL
new file mode 100644
index 0000000..ff8910a
--- /dev/null
+++ b/ext/vec/Makefile.PL
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+ VERSION_FROM => "vec.pm",
+ NAME => "vec",
+ OPTIMIZE => '-g',
+);
diff --git a/ext/vec/t/vec.t b/ext/vec/t/vec.t
new file mode 100644
index 0000000..57a21b2
--- /dev/null
+++ b/ext/vec/t/vec.t
@@ -0,0 +1,30 @@
+#!./perl
+
+BEGIN {
+ unless (-d 'blib') {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ }
+}
+
+use Test::More tests => 15;
+use vec;
+
+ok(vec::->VERSION);
+
+ok(insert_low_bits("", 1) eq "\x00" );
+ok(insert_low_bits("", 8) eq "\x00" );
+ok(insert_low_bits("", 9) eq "\x00\x00");
+ok(insert_low_bits("\x01", 0) eq "\x01" );
+ok(insert_low_bits("\x01", 1) eq "\x02" );
+ok(insert_low_bits("\x01", 7) eq "\x80" );
+ok(insert_low_bits("\x01", 8) eq "\x00\x01");
+
+ok(remove_low_bits("", 1) eq "" );
+ok(remove_low_bits("\x01", 0) eq "\x01");
+ok(remove_low_bits("\x01", 1) eq "" );
+ok(remove_low_bits("\x00\x01", 8) eq "\x01");
+ok(remove_low_bits("\x00\x01", 9) eq "" );
+ok(remove_low_bits("\x80", 7) eq "\x01");
+ok(remove_low_bits("\x00\x80", 15) eq "\x01");
+
diff --git a/ext/vec/vec.pm b/ext/vec/vec.pm
new file mode 100644
index 0000000..1f6e06c
--- /dev/null
+++ b/ext/vec/vec.pm
@@ -0,0 +1,69 @@
+# vec.pm
+#
+# Copyright (c) 2008 Chip Salzenberg <[email protected]>. All rights reserved.
+# This program is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+package vec;
+
+use strict;
+
+require Exporter;
+
+our $VERSION = 0.01;
+our $XS_VERSION = $VERSION;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(insert_low_bits remove_low_bits);
+our @EXPORT_OK = @EXPORT;
+
+require XSLoader;
+XSLoader::load('vec', $XS_VERSION);
+
+1;
+
+__END__
+
+=head1 vec
+
+vec - Bit-vector functions not provided by the base language
+
+=head1 SYNOPSIS
+
+ use vec qw(insert_low_bits remove_low_bits);
+ use vec; # same as above
+
+=head1 DESCRIPTION
+
+The C<vec> module provides some bit vector functionality that perhaps could
+have been part of the base language, but aren't, and for reasons of backward
+compatibility now cannot be.
+
+=over 4
+
+=item insert_low_bits STRING, COUNT
+
+Accept a bitvector STRING, a la L<vec>, and an integral bit COUNT. Return a
+new bitvector that is a copy of the original STRING but with COUNT zero bits
+inserted at the low end of the vector; that is, at the front of the string.
+COUNT must be nonnegative.
+
+=item remove_low_bits STRING, COUNT
+
+Accept a bitvector STRING, a la L<vec>, and an integral bit COUNT. Return a
+new bitvector that is a copy of the original STRING but with COUNT bits
+removed from the low end of the vector; that is, from the front of the
+string.
+
+=back
+
+=head1 SEE ALSO
+
+L<vec>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2008 Chip Salzenberg <[email protected]>. All rights reserved.
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
diff --git a/ext/vec/vec.xs b/ext/vec/vec.xs
new file mode 100644
index 0000000..41d45e8
--- /dev/null
+++ b/ext/vec/vec.xs
@@ -0,0 +1,83 @@
+/* Copyright (c) 2008 Graham Barr <[email protected]>. All rights reserved.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the same terms as Perl itself.
+ */
+
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+
+MODULE=vec PACKAGE=vec
+
+PROTOTYPES: DISABLE
+
+SV *
+insert_low_bits(ssv, shift)
+ SV * ssv
+ IV shift
+ PREINIT:
+ size_t len;
+ const char * const s = SvPV_const(ssv, len);
+ UV ibytes, ibits, iextra;
+ char *d;
+ CODE:
+ if (shift < 0)
+ croak("invalid left shift");
+ ibytes = shift >> 3;
+ ibits = shift & 7;
+ iextra = ibits && (!len || ((unsigned char)s[len - 1] >> (8 - ibits)));
+ RETVAL = newSV(len + ibytes + iextra + 1);
+ d = SvPVX(RETVAL);
+ Zero(d, ibytes, char);
+ d += ibytes;
+ if (!ibits) {
+ Copy(s, d, len, char);
+ d += len;
+ }
+ else {
+ size_t i;
+ *d++ = (unsigned char)s[0] << ibits;
+ for (i = 1; i < len + iextra; ++i)
+ *d++ = ((unsigned char)s[i ] << ibits ) |
+ ((unsigned char)s[i-1] >> (8 - ibits));
+ }
+ *d = '\0';
+ SvCUR_set(RETVAL, d - SvPVX_const(RETVAL));
+ SvPOK_on(RETVAL);
+ OUTPUT:
+ RETVAL
+
+SV *
+remove_low_bits(ssv, shift)
+ SV * ssv
+ IV shift
+ PREINIT:
+ size_t len;
+ const char * const s = SvPV_const(ssv, len);
+ UV rbytes, rbits, rextra;
+ char *d;
+ CODE:
+ if (shift < 0)
+ croak("invalid left shift");
+ rbytes = shift >> 3;
+ rbits = shift & 7;
+ rextra = rbits && len && !((unsigned char)s[len - 1] >> rbits);
+ if (len <= rbytes + rextra)
+ XSRETURN_PVN("", 0);
+ RETVAL = newSV(len - (rbytes + rextra) + 1);
+ d = SvPVX(RETVAL);
+ if (!rbits) {
+ Copy(s + rbytes, d, len - rbytes, char);
+ d += len - rbytes;
+ }
+ else {
+ size_t i;
+ for (i = rbytes; i < len - rextra; ++i)
+ *d++ = ((unsigned char)s[i ] >> rbits ) |
+ ((unsigned char)s[i+1] << (8 - rbits));
+ }
+ *d = '\0';
+ SvCUR_set(RETVAL, d - SvPVX_const(RETVAL));
+ SvPOK_on(RETVAL);
+ OUTPUT:
+ RETVAL
-- Chip Salzenberg <chip@pobox.com> |
From @rgs2008/11/17 Chip Salzenberg <chip@pobox.com>:
I expect this one will need to be dual-lived. At which point occurs the Some minor nits:
à la L<perlfunc/vec>
What about "shift" and "unshift" instead of insert and remove ?
Add to that C<MAN3PODS => {}> (to avoid converting the manpage needlessly)
Maybe add some tests with strings flagged as utf8 ? Just to be sure it
You're Graham Barr in disguise ? :) |
From [email protected]Quoth chip@pobox.com (Chip Salzenberg):
"shiftdown" and "shiftup"? Although, given that it only works on Ben |
From @timbunceOn Mon, Nov 17, 2008 at 03:21:29AM -0800, Chip Salzenberg wrote:
The function name makes me think I can supply the bits that will be Instead of focussing on just these two shift operations I wonder if an splicebits VEC,OFFSET,LENGTH,LIST subbits VEC,OFFSET,LENGTH,REPLACEMENT With more specialized functions implemented, or at least specified, in Just a thought. Tim. |
From [email protected]
I concur. When I was writing Scalar::Vec::Util, I felt like the atomic Vincent. |
From @nwc10On Mon, Nov 17, 2008 at 12:43:39PM +0100, Rafael Garcia-Suarez wrote:
Yes, this was my thought too. If it exists, and it's not the default, and you Nicholas Clark |
From @chipdudeOn Mon, Nov 17, 2008 at 02:27:17PM +0100, Vincent Pit wrote:
Your Calar::Vec::Util::vcopy method ... does it work with overlapping |
From @chipdudeOn Mon, Nov 17, 2008 at 01:31:11PM +0000, Nicholas Clark wrote:
I agree. Since the original reporter was Jarkko, and he asked for a language |
From @chipdudeOn Mon, Nov 17, 2008 at 09:04:12AM -0800, Chip Salzenberg wrote:
Silly me, RTFM: vcopy $t, 10, $t, 20, 30; # Overalapping areas DWIM. OK, I'm calling the bug closed. Thanks, Vincent. |
@chipdude - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#969 (status was 'resolved')
Searchable as RT969$
The text was updated successfully, but these errors were encountered: