From 8d3e3cb5ea26849738e3a78f891b453b781fe898 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 20:40:45 -0800 Subject: [PATCH 01/11] First commit --- Gemfile | 2 ++ Gemfile.lock | 20 +++++++++++++ README | 1 + README.md | 3 ++ Rakefile | 21 +++++++++++++ bitarray.gemspec | 24 +++++++++++++++ lib/bit_array.rb | 67 ++++++++++++++++++++++++++++++++++++++++++ test/test_bit_array.rb | 62 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 README create mode 100644 README.md create mode 100644 Rakefile create mode 100644 bitarray.gemspec create mode 100644 lib/bit_array.rb create mode 100644 test/test_bit_array.rb diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..1aa98e4 --- /dev/null +++ b/Gemfile @@ -0,0 +1,2 @@ +source "http://rubygems.org" +gemspec diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..bceccef --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,20 @@ +PATH + remote: . + specs: + bit-array (0.0.4) + +GEM + remote: http://rubygems.org/ + specs: + rake (0.9.2.2) + test-unit (2.4.5) + yard (0.7.4) + +PLATFORMS + ruby + +DEPENDENCIES + bit-array! + rake + test-unit + yard diff --git a/README b/README new file mode 100644 index 0000000..ec8472e --- /dev/null +++ b/README @@ -0,0 +1 @@ +This file was created by JetBrains RubyMine 3.2.4 for binding GitHub repository \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9312a38 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# BitArray: A fast(ish), pure Ruby bit field "type" + +This is a simple rubygem wrapper for the class written by Peter Cooper and posted to dzone. \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..cfa06cb --- /dev/null +++ b/Rakefile @@ -0,0 +1,21 @@ +begin + require 'bundler/setup' +rescue LoadError + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +end + +Bundler::GemHelper.install_tasks + +require 'yard' +YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb', 'README.md'] +end + +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs << 'test' +end + +desc "Run tests" +task :default => :test diff --git a/bitarray.gemspec b/bitarray.gemspec new file mode 100644 index 0000000..2b2ff8f --- /dev/null +++ b/bitarray.gemspec @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "bit_array" + +Gem::Specification.new do |s| + s.name = "bit-array" + s.version = BitArray::VERSION + s.authors = ["Peter Cooper"] + s.email = ["git@peterc.org"] + s.homepage = "https://github.com/mceachen/bit-array/" + s.summary = %q{A fast(ish), pure Ruby bit field "type"} + s.description = %q{Rubygem packaging of Peter Cooper's BitArray class'} + + s.rubyforge_project = "bit-array" + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.require_paths = ["lib"] + + s.add_development_dependency "rake" + s.add_development_dependency "yard" + s.add_development_dependency "test-unit" +end diff --git a/lib/bit_array.rb b/lib/bit_array.rb new file mode 100644 index 0000000..3702daa --- /dev/null +++ b/lib/bit_array.rb @@ -0,0 +1,67 @@ +# NAME: BitArray +# AUTHOR: Peter Cooper +# LICENSE: MIT ( http://www.opensource.org/licenses/mit-license.php ) +# COPYRIGHT: (c) 2007 Peter Cooper (http://www.petercooper.co.uk/) +# VERSION: v4 +# HISTORY: v4 (fixed bug where setting 0 bits to 0 caused a set to 1) +# v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) +# v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) +# v1 (first release) +# +# DESCRIPTION: Basic, pure Ruby bit field. Pretty fast (for what it is) and memory efficient. +# I've written a pretty intensive test suite for it and it passes great. +# Works well for Bloom filters (the reason I wrote it). +# +# Create a bit field 1000 bits wide +# bf = BitField.new(1000) +# +# Setting and reading bits +# bf[100] = 1 +# bf[100] .. => 1 +# bf[100] = 0 +# +# More +# bf.to_s = "10101000101010101" (example) +# bf.total_set .. => 10 (example - 10 bits are set to "1") + +class BitArray + attr_reader :size + include Enumerable + VERSION = "0.0.4" + ELEMENT_WIDTH = 32 + + def initialize(size) + @size = size + @field = Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0) + end + + # Set a bit (1/0) + def []=(position, value) + if value == 1 + @field[position / ELEMENT_WIDTH] |= 1 << (position % ELEMENT_WIDTH) + elsif (@field[position / ELEMENT_WIDTH]) & (1 << (position % ELEMENT_WIDTH)) != 0 + @field[position / ELEMENT_WIDTH] ^= 1 << (position % ELEMENT_WIDTH) + end + end + + # Read a bit (1/0) + def [](position) + @field[position / ELEMENT_WIDTH] & 1 << (position % ELEMENT_WIDTH) > 0 ? 1 : 0 + end + + # Iterate over each bit + def each(&block) + @size.times { |position| yield self[position] } + end + + # Returns the field as a string like "0101010100111100," etc. + def to_s + inject("") { |a, b| a + b.to_s } + end + + # Returns the total number of bits that are set + # (The technique used here is about 6 times faster than using each or inject direct on the bitfield) + def total_set + @field.inject(0) { |a, byte| a += byte & 1 and byte >>= 1 until byte == 0; a } + end +end \ No newline at end of file diff --git a/test/test_bit_array.rb b/test/test_bit_array.rb new file mode 100644 index 0000000..65161df --- /dev/null +++ b/test/test_bit_array.rb @@ -0,0 +1,62 @@ +require "test/unit" + +class TestBitArray < Test::Unit::TestCase + + def setup + @public_bf = BitArray.new(1000) + end + + def test_basic + assert_equal 0, BitArray.new(100)[0] + assert_equal 0, BitArray.new(100)[1] + end + + def test_setting_and_unsetting + @public_bf[100] = 1 + assert_equal 1, @public_bf[100] + @public_bf[100] = 0 + assert_equal 0, @public_bf[100] + end + + def test_random_setting_and_unsetting + 100.times do + index = rand(1000) + @public_bf[index] = 1 + assert_equal 1, @public_bf[index] + @public_bf[index] = 0 + assert_equal 0, @public_bf[index] + end + end + + def test_multiple_setting + 1.upto(999) do |pos| + 2.times { @public_bf[pos] = 1 } + assert_equal 1, @public_bf[pos] + end + end + + def test_multiple_unsetting + 1.upto(999) do |pos| + 2.times { @public_bf[pos] = 0 } + assert_equal 0, @public_bf[pos] + end + end + + def test_size + assert_equal 1000, @public_bf.size + end + + def test_to_s + bf = BitArray.new(10) + bf[1] = 1 + bf[5] = 1 + assert_equal "0100010000", bf.to_s + end + + def test_total_set + bf = BitArray.new(10) + bf[1] = 1 + bf[5] = 1 + assert_equal 2, bf.total_set + end +end From b7e3b102aa3b772dd716cbc31be5d122a87061ec Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 20:44:47 -0800 Subject: [PATCH 02/11] fixed gemspec name --- .gitignore | 6 ++++++ Gemfile.lock | 4 ++-- bitarray.gemspec | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b73f40c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.gem +.idea/ +.yardoc/ +.bundle/ +Gemfile.lock +pkg/ diff --git a/Gemfile.lock b/Gemfile.lock index bceccef..1473c9e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - bit-array (0.0.4) + bitarray (0.0.4) GEM remote: http://rubygems.org/ @@ -14,7 +14,7 @@ PLATFORMS ruby DEPENDENCIES - bit-array! + bitarray! rake test-unit yard diff --git a/bitarray.gemspec b/bitarray.gemspec index 2b2ff8f..aed2115 100644 --- a/bitarray.gemspec +++ b/bitarray.gemspec @@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__) require "bit_array" Gem::Specification.new do |s| - s.name = "bit-array" + s.name = "bitarray" s.version = BitArray::VERSION s.authors = ["Peter Cooper"] s.email = ["git@peterc.org"] @@ -11,7 +11,7 @@ Gem::Specification.new do |s| s.summary = %q{A fast(ish), pure Ruby bit field "type"} s.description = %q{Rubygem packaging of Peter Cooper's BitArray class'} - s.rubyforge_project = "bit-array" + s.rubyforge_project = "bitarray" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") From 28ea0c59d89eb00a7fda4df783656f84e254d9e3 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 20:47:01 -0800 Subject: [PATCH 03/11] removed README stub --- README | 1 - 1 file changed, 1 deletion(-) delete mode 100644 README diff --git a/README b/README deleted file mode 100644 index ec8472e..0000000 --- a/README +++ /dev/null @@ -1 +0,0 @@ -This file was created by JetBrains RubyMine 3.2.4 for binding GitHub repository \ No newline at end of file From 88975ad5b112bb8e40201e22a4442964e8af7d93 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:02:49 -0800 Subject: [PATCH 04/11] added support for default-set bit array --- lib/bit_array.rb | 26 +++++++++++++------------ test/test_bit_array.rb | 43 ++++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/lib/bit_array.rb b/lib/bit_array.rb index 3702daa..b258661 100644 --- a/lib/bit_array.rb +++ b/lib/bit_array.rb @@ -2,37 +2,39 @@ # AUTHOR: Peter Cooper # LICENSE: MIT ( http://www.opensource.org/licenses/mit-license.php ) # COPYRIGHT: (c) 2007 Peter Cooper (http://www.petercooper.co.uk/) -# VERSION: v4 -# HISTORY: v4 (fixed bug where setting 0 bits to 0 caused a set to 1) +# VERSION: v5 +# HISTORY: v5 (added support for flags being on by default, instead of off) +# v4 (fixed bug where setting 0 bits to 0 caused a set to 1) # v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) # v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) # v1 (first release) # -# DESCRIPTION: Basic, pure Ruby bit field. Pretty fast (for what it is) and memory efficient. +# DESCRIPTION: Basic, pure Ruby bit array. Pretty fast (for what it is) and memory efficient. # I've written a pretty intensive test suite for it and it passes great. # Works well for Bloom filters (the reason I wrote it). # -# Create a bit field 1000 bits wide -# bf = BitField.new(1000) +# Create a bit array 1000 bits wide +# ba = BitArray.new(1000) # # Setting and reading bits -# bf[100] = 1 -# bf[100] .. => 1 -# bf[100] = 0 +# ba[100] = 1 +# ba[100] .. => 1 +# ba[100] = 0 # # More -# bf.to_s = "10101000101010101" (example) -# bf.total_set .. => 10 (example - 10 bits are set to "1") +# ba.to_s = "10101000101010101" (example) +# ba.total_set .. => 10 (example - 10 bits are set to "1") class BitArray attr_reader :size include Enumerable - VERSION = "0.0.4" + VERSION = "0.0.5" ELEMENT_WIDTH = 32 - def initialize(size) + def initialize(size, default_value = 0) @size = size @field = Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0) + @field.map!{|i| ~i} if (default_value == 1) end # Set a bit (1/0) diff --git a/test/test_bit_array.rb b/test/test_bit_array.rb index 65161df..249da23 100644 --- a/test/test_bit_array.rb +++ b/test/test_bit_array.rb @@ -3,7 +3,7 @@ class TestBitArray < Test::Unit::TestCase def setup - @public_bf = BitArray.new(1000) + @public_ba = BitArray.new(1000) end def test_basic @@ -12,38 +12,53 @@ def test_basic end def test_setting_and_unsetting - @public_bf[100] = 1 - assert_equal 1, @public_bf[100] - @public_bf[100] = 0 - assert_equal 0, @public_bf[100] + @public_ba[100] = 1 + assert_equal 1, @public_ba[100] + @public_ba[100] = 0 + assert_equal 0, @public_ba[100] end def test_random_setting_and_unsetting 100.times do index = rand(1000) - @public_bf[index] = 1 - assert_equal 1, @public_bf[index] - @public_bf[index] = 0 - assert_equal 0, @public_bf[index] + @public_ba[index] = 1 + assert_equal 1, @public_ba[index] + @public_ba[index] = 0 + assert_equal 0, @public_ba[index] + end + end + + def test_random_side_effects + ba2 = BitArray.new(1000, 1) + + on = 300.times.collect do + index = rand(1000) + @public_ba[index] = 1 + ba2[index] = 0 + index + end + 1000.times do |i| + assert_equal(@public_ba[i], on.include?(i) ? 1 : 0) + assert_equal(ba2[i], on.include?(i) ? 0 : 1) end end def test_multiple_setting 1.upto(999) do |pos| - 2.times { @public_bf[pos] = 1 } - assert_equal 1, @public_bf[pos] + 2.times { @public_ba[pos] = 1 } + assert_equal 1, @public_ba[pos] end end def test_multiple_unsetting 1.upto(999) do |pos| - 2.times { @public_bf[pos] = 0 } - assert_equal 0, @public_bf[pos] + 2.times { @public_ba[pos] = 0 } + assert_equal 0, @public_ba[pos] end end def test_size - assert_equal 1000, @public_bf.size + assert_equal 1000, @public_ba.size end def test_to_s From 416df905e574c94325abaed6651b94c26ece7921 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:22:35 -0800 Subject: [PATCH 05/11] fixed name, added to readme --- Gemfile.lock | 2 +- README.md | 33 ++++++++++++++++++++++++++++++- bitarray.gemspec | 2 +- lib/{bit_array.rb => bitarray.rb} | 0 4 files changed, 34 insertions(+), 3 deletions(-) rename lib/{bit_array.rb => bitarray.rb} (100%) diff --git a/Gemfile.lock b/Gemfile.lock index 1473c9e..251ecfa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - bitarray (0.0.4) + bitarray (0.0.5) GEM remote: http://rubygems.org/ diff --git a/README.md b/README.md index 9312a38..55ff970 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,34 @@ # BitArray: A fast(ish), pure Ruby bit field "type" -This is a simple rubygem wrapper for the class written by Peter Cooper and posted to dzone. \ No newline at end of file +This is a simple rubygem wrapper for the class written by Peter Cooper and posted to dzone. + +## History +v5 (added support for flags being on by default, instead of off) +# v4 (fixed bug where setting 0 bits to 0 caused a set to 1) +# v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) +# v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) +# v1 (first release) +# +# Description +Basic, pure Ruby bit array. Pretty fast (for what it is) and memory efficient. +Works well for Bloom filters (the reason I wrote it). + +Create a bit array 1000 bits wide +```ruby ba = BitArray.new(1000)``` + +Setting and reading bits +```ruby + ba[100] = 1 + ba[100] .. => 1 + ba[100] = 0 +``` + +More +```ruby + ba = BitArray.new(20) + [1,3,5,9,11,13,15].each { |i| ba[i] = 1 } + ba.to_s + #=> "01010100010101010000" + ba.total_set + #=> 7 +``` \ No newline at end of file diff --git a/bitarray.gemspec b/bitarray.gemspec index aed2115..02fe31b 100644 --- a/bitarray.gemspec +++ b/bitarray.gemspec @@ -1,6 +1,6 @@ # -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) -require "bit_array" +require "bitarray" Gem::Specification.new do |s| s.name = "bitarray" diff --git a/lib/bit_array.rb b/lib/bitarray.rb similarity index 100% rename from lib/bit_array.rb rename to lib/bitarray.rb From 430e8ba34ad23efdaa6eee58de7acc94d55e3f97 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:24:47 -0800 Subject: [PATCH 06/11] doc twiddle --- README.md | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 55ff970..0c5de89 100644 --- a/README.md +++ b/README.md @@ -3,32 +3,34 @@ This is a simple rubygem wrapper for the class written by Peter Cooper and posted to dzone. ## History -v5 (added support for flags being on by default, instead of off) -# v4 (fixed bug where setting 0 bits to 0 caused a set to 1) -# v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) -# v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) -# v1 (first release) -# -# Description +- v5 (added support for flags being on by default, instead of off) +- v4 (fixed bug where setting 0 bits to 0 caused a set to 1) +- v3 (supports dynamic bitwidths for array elements.. now doing 32 bit widths default) +- v2 (now uses 1 << y, rather than 2 ** y .. it's 21.8 times faster!) +- v1 (first release) + +## Description Basic, pure Ruby bit array. Pretty fast (for what it is) and memory efficient. Works well for Bloom filters (the reason I wrote it). Create a bit array 1000 bits wide -```ruby ba = BitArray.new(1000)``` +```ruby + ba = BitArray.new(1000) +``` Setting and reading bits ```ruby - ba[100] = 1 - ba[100] .. => 1 - ba[100] = 0 +ba[100] = 1 +ba[100] .. => 1 +ba[100] = 0 ``` More ```ruby - ba = BitArray.new(20) - [1,3,5,9,11,13,15].each { |i| ba[i] = 1 } - ba.to_s - #=> "01010100010101010000" - ba.total_set - #=> 7 +ba = BitArray.new(20) +[1,3,5,9,11,13,15].each { |i| ba[i] = 1 } +ba.to_s +#=> "01010100010101010000" +ba.total_set +#=> 7 ``` \ No newline at end of file From 6ae1ba67b8eb96d6253d414b5ea6da8fe25ffd0d Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:26:33 -0800 Subject: [PATCH 07/11] hate the .md --- README.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0c5de89..cf21abb 100644 --- a/README.md +++ b/README.md @@ -13,24 +13,27 @@ This is a simple rubygem wrapper for the class written by Peter Cooper and poste Basic, pure Ruby bit array. Pretty fast (for what it is) and memory efficient. Works well for Bloom filters (the reason I wrote it). -Create a bit array 1000 bits wide +Create a bit array 1000 bits wide: + ```ruby ba = BitArray.new(1000) ``` -Setting and reading bits +Setting and reading bits: + ```ruby -ba[100] = 1 -ba[100] .. => 1 -ba[100] = 0 + ba[100] = 1 + ba[100] .. => 1 + ba[100] = 0 ``` -More +More: + ```ruby -ba = BitArray.new(20) -[1,3,5,9,11,13,15].each { |i| ba[i] = 1 } -ba.to_s -#=> "01010100010101010000" -ba.total_set -#=> 7 + ba = BitArray.new(20) + [1,3,5,9,11,13,15].each { |i| ba[i] = 1 } + ba.to_s + #=> "01010100010101010000" + ba.total_set + #=> 7 ``` \ No newline at end of file From 395691d86dd6ab388eb326ea2c6277217e803a0c Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:27:11 -0800 Subject: [PATCH 08/11] hate the .md --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cf21abb..0891799 100644 --- a/README.md +++ b/README.md @@ -16,24 +16,24 @@ Works well for Bloom filters (the reason I wrote it). Create a bit array 1000 bits wide: ```ruby - ba = BitArray.new(1000) +ba = BitArray.new(1000) ``` Setting and reading bits: ```ruby - ba[100] = 1 - ba[100] .. => 1 - ba[100] = 0 +ba[100] = 1 +ba[100] .. => 1 +ba[100] = 0 ``` More: ```ruby - ba = BitArray.new(20) - [1,3,5,9,11,13,15].each { |i| ba[i] = 1 } - ba.to_s - #=> "01010100010101010000" - ba.total_set - #=> 7 +ba = BitArray.new(20) +[1,3,5,9,11,13,15].each { |i| ba[i] = 1 } +ba.to_s +#=> "01010100010101010000" +ba.total_set +#=> 7 ``` \ No newline at end of file From a35e20e7ada787bdf0e83cba5cf18d97dac9247b Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:28:35 -0800 Subject: [PATCH 09/11] hate the .md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0891799..4537e94 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,12 @@ Setting and reading bits: ```ruby ba[100] = 1 -ba[100] .. => 1 +ba[100] +#=> 1 + ba[100] = 0 +ba[100] +#=> 0 ``` More: From ee0d8b4c6e62629457ccc99f363d4a1fd79c5ce7 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Tue, 17 Jan 2012 21:33:55 -0800 Subject: [PATCH 10/11] rename to cleanup merge --- test/{test_bit_array.rb => test_bitarray.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{test_bit_array.rb => test_bitarray.rb} (100%) diff --git a/test/test_bit_array.rb b/test/test_bitarray.rb similarity index 100% rename from test/test_bit_array.rb rename to test/test_bitarray.rb From 265f33b291b444407a45c39d2bc3abf879eb8d91 Mon Sep 17 00:00:00 2001 From: Matthew McEachen Date: Wed, 18 Jan 2012 10:42:00 -0800 Subject: [PATCH 11/11] to_s's inject was AMAZINGLY slow, and added int-boundary test. --- lib/bitarray.rb | 2 +- test/test_bitarray.rb | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/bitarray.rb b/lib/bitarray.rb index eb9a169..3220255 100644 --- a/lib/bitarray.rb +++ b/lib/bitarray.rb @@ -31,7 +31,7 @@ def each(&block) # Returns the field as a string like "0101010100111100," etc. def to_s - inject("") { |a, b| a + b.to_s } + @field.collect{|ea| ("%032b" % ea).reverse}.join[0..@size-1] end # Returns the total number of bits that are set diff --git a/test/test_bitarray.rb b/test/test_bitarray.rb index 38b5be3..7ec27c6 100644 --- a/test/test_bitarray.rb +++ b/test/test_bitarray.rb @@ -30,15 +30,17 @@ def test_random_setting_and_unsetting end def test_random_side_effects - ba2 = BitArray.new(1000, 1) + ba2 = BitArray.new(@public_ba.size, 1) - on = 300.times.collect do - index = rand(1000) + on = (@public_ba.size / 2).times.collect do + index = rand(@public_ba.size) @public_ba[index] = 1 ba2[index] = 0 index end - 1000.times do |i| + assert_equal(@public_ba.to_s, @public_ba.to_s_fast) + + @public_ba.size.times do |i| assert_equal(@public_ba[i], on.include?(i) ? 1 : 0) assert_equal(ba2[i], on.include?(i) ? 0 : 1) end @@ -63,10 +65,9 @@ def test_size end def test_to_s - ba = BitArray.new(10) - ba[1] = 1 - ba[5] = 1 - assert_equal "0100010000", ba.to_s + ba = BitArray.new(35) + [1, 5, 6, 7, 10, 16, 33].each{|i|ba[i] = 1} + assert_equal "01000111001000001000000000000000010", ba.to_s end def test_total_set