DEMO.md in radix-2.2.0 vs DEMO.md in radix-2.2.1

- old
+ new

@@ -1,763 +1,782 @@ -= Synopsis +# Synopsis Radix provides the means of converting to and from any base. For example, a number in base 256 can be represented by the array [100, 10] (ie. 100**256 + 10**1) and easily converted to base 10. - [100,10].b(256).to_i #=> 25610 + [100,10].b(256).to_i #=> 25610 We can get an Array representation as well. - [100,10].b(256).to_a(10) #=> [2,5,6,1,0] - [100,10].b(256).to_a(62) #=> [6,41,4] - [100,10].b(256).to_a(64) #=> [6,16,10] + [100,10].b(256).to_a(10) #=> [2,5,6,1,0] + [100,10].b(256).to_a(62) #=> [6,41,4] + [100,10].b(256).to_a(64) #=> [6,16,10] To get a String representation for any base use #to_s. - [100,10].b(256).to_s(10) #=> "25610" - [100,10].b(256).to_s(62) #=> "6 41 4" - [100,10].b(256).to_s(64) #=> "6 16 10" + [100,10].b(256).to_s(10) #=> "25610" + [100,10].b(256).to_s(62) #=> "6 41 4" + [100,10].b(256).to_s(64) #=> "6 16 10" Notice that anything above base 10 is seperated by a space divider. The divider can be changed by providing a second argument. - [100,10].b(256).to_s(64, ':') #=> "6:16:10" + [100,10].b(256).to_s(64, ':') #=> "6:16:10" A string representation of a number can be converted upto base 62 (B62). - "10".b(62).to_s(10) #=> "62" - "zz".b(62).to_s(10) #=> "3843" + "10".b(62).to_s(10) #=> "62" + "zz".b(62).to_s(10) #=> "3843" To encode a number with a base greater than 10, use an Array base. Radix provides a built-in set of these, such as `BASE::B62`. - [100,10].b(256).to_s(Radix::BASE::B62) #=> "6f4" + [100,10].b(256).to_s(Radix::BASE::B62) #=> "6f4" To use a custom character set, use an array of characters as the base rather than an integer. For example we can convert a base 10 number to another base 10 number but useing a different encoding. - base = %w[Q W E R T Y U I O U] + base = %w[Q W E R T Y U I O U] - "10".b(10).to_a(base) #=> ["W", "Q"] + "10".b(10).to_a(base) #=> ["W", "Q"] - "10".b(10).to_s(base) #=> "WQ" + "10".b(10).to_s(base) #=> "WQ" All of the above holds equally for floating point numbers. -= Radix Integer +# Radix Integer Radix provides an Integer class for working with integers in various bases. - require 'radix' + require 'radix' -== Initialization +## Initialization Radix::Integer's initializer can accept either an Integer, String or Array as a value and an integer base. Give an integer value, it will automatically be converted to the base specified. - check do |integer, base, digits| - r = Radix::Integer.new(integer, base) - r.digits.assert == digits - end + check do |integer, base, digits| + r = Radix::Integer.new(integer, base) + r.digits.assert == digits + end - ok 8, 2, [1,0,0,0] - ok 4, 2, [1,0,0] - ok 8, 10, [8] - ok 10, 10, [1, 0] - ok 8, 16, [8] - ok 16, 16, [1, 0] + ok 8, 2, [1,0,0,0] + ok 4, 2, [1,0,0] + ok 8, 10, [8] + ok 10, 10, [1, 0] + ok 8, 16, [8] + ok 16, 16, [1, 0] Where as a String value is taken to already be in the base given. - ok "1000", 2, [1,0,0,0] - ok "100", 2, [1,0,0] + ok "1000", 2, [1,0,0,0] + ok "100", 2, [1,0,0] - ok "8", 10, [8] - ok "10", 10, [1, 0] - ok "8", 16, [8] - ok "10", 16, [1, 0] + ok "8", 10, [8] + ok "10", 10, [1, 0] + ok "8", 16, [8] + ok "10", 16, [1, 0] And an Array is also taken to be in the base given. - ok %w[1 0 0 0], 2, [1,0,0,0] - ok %w[ 1 0 0], 2, [1,0,0] + ok %w[1 0 0 0], 2, [1,0,0,0] + ok %w[ 1 0 0], 2, [1,0,0] - ok %w[ 8], 10, [8] - ok %w[1 0], 10, [1, 0] - ok %w[ 8], 16, [8] - ok %w[1 0], 16, [1, 0] + ok %w[ 8], 10, [8] + ok %w[1 0], 10, [1, 0] + ok %w[ 8], 16, [8] + ok %w[1 0], 16, [1, 0] Integers can also be negative, rather than positive. In each case just prepend the value with a minus sign. - check do |integer, base, digits| - r = Radix::Integer.new(integer, base) - r.digits.assert == digits - r.assert.negative? - end + check do |integer, base, digits| + r = Radix::Integer.new(integer, base) + r.digits.assert == digits + r.assert.negative? + end - ok -8, 2, ['-',1,0,0,0] - ok "-1000", 2, ['-',1,0,0,0] - ok %w[- 1 0 0 0], 2, ['-',1,0,0,0] + ok -8, 2, ['-',1,0,0,0] + ok "-1000", 2, ['-',1,0,0,0] + ok %w[- 1 0 0 0], 2, ['-',1,0,0,0] If a value has a digit outside of the range of the base an ArgumentError will be raised. - expect ArgumentError do - Radix::Integer.new('9', 2) - end + expect ArgumentError do + Radix::Integer.new('9', 2) + end Radix provides a convenience extension method to Integer, String and Array called #b, to more easily initialize a Radix numeric object. The method simply passes the receiver on to `Radix::Integer#new`. - check do |integer, base, digits| - r = integer.b(base) - r.assert.is_a?(Radix::Integer) - r.digits.assert == digits - end + check do |integer, base, digits| + r = integer.b(base) + r.assert.is_a?(Radix::Integer) + r.digits.assert == digits + end - ok 8, 2, [1,0,0,0] - ok 4, 2, [1,0,0] + ok 8, 2, [1,0,0,0] + ok 4, 2, [1,0,0] - ok "1000", 2, [1,0,0,0] - ok "100", 2, [1,0,0] + ok "1000", 2, [1,0,0,0] + ok "100", 2, [1,0,0] - ok %w"1 0 0 0", 2, [1,0,0,0] - ok %w"1 0 0", 2, [1,0,0] + ok %w"1 0 0 0", 2, [1,0,0,0] + ok %w"1 0 0", 2, [1,0,0] -== Conversion +## Conversion Radix integers can ve converted to other bases with the #convert method. - b = "1000".b(2) - d = b.convert(10) - d.digits.assert == [8] + b = "1000".b(2) + d = b.convert(10) + d.digits.assert == [8] We can convert a Radix::Integer to a regular base-10 Integer with the #to_i method. - b = "1000".b(2) - d = b.to_i - d.assert == 8 + b = "1000".b(2) + d = b.to_i + d.assert == 8 -== Equality +## Equality Radix extend the Integer, String and Array classes with the #b method which simplifies the creation of Radix::Integer instances. The following return the equivalent instance of Radix::Integer. - a = 8.b(2) - b = "1000".b(2) - c = [1, 0, 0, 0].b(2) + a = 8.b(2) + b = "1000".b(2) + c = [1, 0, 0, 0].b(2) - a.assert == b - b.assert == c - c.assert == a + a.assert == b + b.assert == c + c.assert == a - a.assert == 8 - b.assert == 8 - c.assert == 8 + a.assert == 8 + b.assert == 8 + c.assert == 8 More stringent equality can be had from #eql?, in which the other integer must be a Radix::Integer too. - a.assert.eql?(b) - a.refute.eql?(8) + a.assert.eql?(b) + a.refute.eql?(8) -== Operations +## Operations Radix::Integer supports all the usual mathematical operators. -=== Addition +### Addition - check do |a, b, x| - (a + b).assert == x - end + check do |a, b, x| + (a + b).assert == x + end - ok "1000".b(2), "0010".b(2), "1010".b(2) - ok "1000".b(2), "2".b(8), "1010".b(2) - ok "1000".b(2), "2".b(8), "10".b(10) + ok "1000".b(2), "0010".b(2), "1010".b(2) + ok "1000".b(2), "2".b(8), "1010".b(2) + ok "1000".b(2), "2".b(8), "10".b(10) A more complex example. - x = "AZ42".b(62) + "54".b(10) - x.assert == "2518124".b(10) - x.assert == 2518124 + x = "AZ42".b(62) + "54".b(10) + x.assert == "2518124".b(10) + x.assert == 2518124 Adding negative integers will, of course, be akin to subtraction. - ok "1000".b(2), "-0010".b(2), "110".b(2) - ok "1000".b(2), "-2".b(8), "110".b(2) - ok "1000".b(2), "-2".b(8), "6".b(10) + ok "1000".b(2), "-0010".b(2), "110".b(2) + ok "1000".b(2), "-2".b(8), "110".b(2) + ok "1000".b(2), "-2".b(8), "6".b(10) - ok "-1000".b(2), "0010".b(2), "-110".b(2) - ok "-1000".b(2), "2".b(8), "-110".b(2) - ok "-1000".b(2), "2".b(8), "-6".b(10) + ok "-1000".b(2), "0010".b(2), "-110".b(2) + ok "-1000".b(2), "2".b(8), "-110".b(2) + ok "-1000".b(2), "2".b(8), "-6".b(10) - ok "-1000".b(2), "-0010".b(2), "-1010".b(2) - ok "-1000".b(2), "-2".b(8), "-1010".b(2) - ok "-1000".b(2), "-2".b(8), "-10".b(10) + ok "-1000".b(2), "-0010".b(2), "-1010".b(2) + ok "-1000".b(2), "-2".b(8), "-1010".b(2) + ok "-1000".b(2), "-2".b(8), "-10".b(10) -=== Subtraction +### Subtraction - check do |a, b, x| - (a - b).assert == x - end + check do |a, b, x| + (a - b).assert == x + end - ok "1000".b(2), "10".b(2), "0110".b(2) - ok "1000".b(2), "2".b(8), "0110".b(2) - ok "1000".b(2), "2".b(8), "6".b(8) - ok "1000".b(2), "2".b(8), "6".b(10) + ok "1000".b(2), "10".b(2), "0110".b(2) + ok "1000".b(2), "2".b(8), "0110".b(2) + ok "1000".b(2), "2".b(8), "6".b(8) + ok "1000".b(2), "2".b(8), "6".b(10) A more complex example. - x = "AZ42".b(62) - "54".b(10) - x.assert == "2518016".b(10) - x.assert == 2518016 + x = "AZ42".b(62) - "54".b(10) + x.assert == "2518016".b(10) + x.assert == 2518016 -=== Multiplication +### Multiplication - check do |a, b, x| - (a * b).assert == x - end + check do |a, b, x| + (a * b).assert == x + end - ok "1000".b(2), "10".b(2), "10000".b(2) - ok "1000".b(2), "2".b(8), "10000".b(2) - ok "1000".b(2), "2".b(8), "20".b(8) - ok "1000".b(2), "2".b(8), "16".b(10) + ok "1000".b(2), "10".b(2), "10000".b(2) + ok "1000".b(2), "2".b(8), "10000".b(2) + ok "1000".b(2), "2".b(8), "20".b(8) + ok "1000".b(2), "2".b(8), "16".b(10) A more complex example. - x = "Z42".b(62) * "4".b(10) - x.assert == "539160".b(10) - x.assert == 539160 + x = "Z42".b(62) * "4".b(10) + x.assert == "539160".b(10) + x.assert == 539160 -=== Division +### Division - check do |a, b, x| - (a / b).assert == x - end + check do |a, b, x| + (a / b).assert == x + end - ok "1000".b(2), "10".b(2), "100".b(2) - ok "1000".b(2), "2".b(8), "100".b(2) - ok "1000".b(2), "2".b(8), "4".b(8) - ok "1000".b(2), "2".b(8), "4".b(10) + ok "1000".b(2), "10".b(2), "100".b(2) + ok "1000".b(2), "2".b(8), "100".b(2) + ok "1000".b(2), "2".b(8), "4".b(8) + ok "1000".b(2), "2".b(8), "4".b(10) A more complex example. - x = "AZ42".b(62) / "54".b(10) - x.assert == "46630".b(10) - x.assert == 46630 + x = "AZ42".b(62) / "54".b(10) + x.assert == "46630".b(10) + x.assert == 46630 -=== Power +### Power - check do |a, b, x| - (a ** b).assert == x - end + check do |a, b, x| + (a ** b).assert == x + end - ok "1000".b(2), "10".b(2), 64 + ok "1000".b(2), "10".b(2), 64 -=== Modulo +### Modulo - check do |a, b, x| - (a % b).assert == x - end + check do |a, b, x| + (a % b).assert == x + end - ok "1000".b(2), "10".b(2), 0 - ok "1000".b(2), "11".b(2), 2 + ok "1000".b(2), "10".b(2), 0 + ok "1000".b(2), "11".b(2), 2 -=== Bitwise Shift +### Bitwise Shift - check do |a, b, x| - (a << b).assert == x - end + check do |a, b, x| + (a << b).assert == x + end - ok "10".b(2), "10".b(2), "1000".b(2) - ok "10".b(2), 2, "1000".b(2) - ok "10".b(2), 2, 8 + ok "10".b(2), "10".b(2), "1000".b(2) + ok "10".b(2), 2, "1000".b(2) + ok "10".b(2), 2, 8 -=== Bitwise AND +### Bitwise AND - check do |a, b, x| - (a & b).assert == x - end + check do |a, b, x| + (a & b).assert == x + end - ok "1010".b(2), "10".b(2), "10".b(2) - ok "1010".b(2), "2".b(8), "10".b(2) + ok "1010".b(2), "10".b(2), "10".b(2) + ok "1010".b(2), "2".b(8), "10".b(2) -== Coerce +## Coerce When a Radix::Integer is the operand in an operation against a regular Ruby Integer, the calculation should still work via #coerce. - check do |a, b, x| - (a + b).assert == x - end + check do |a, b, x| + (a + b).assert == x + end - ok 10, "10".b(2), "12".b(10) + ok 10, "10".b(2), "12".b(10) -= Radix Float +# Radix Float Radix provides a Float class for working with rational numbers in various bases. Actually Radix's implementation of Float is a <i>fixed point</i>, not a -<i>floating point</i>. +*floating point*. - require 'radix' + require 'radix' - D = Radix::DOT + D = Radix::DOT -== Initialization +## Initialization Radix::Float's initializer can accept either an Integer, Float, String or Array as a value and an integer base. Give a float value, it will automatically be converted to the base specified. - check do |float, base, digits| - r = Radix::Float.new(float, base) - r.digits.assert == digits - end + check do |float, base, digits| + r = Radix::Float.new(float, base) + r.digits.assert == digits + end - ok 8.5, 2, [1,0,0,0,D,1] - ok 4.5, 2, [ 1,0,0,D,1] + ok 8.5, 2, [1,0,0,0,D,1] + ok 4.5, 2, [ 1,0,0,D,1] - ok 8.1, 10, [ 8,D,1] - ok 10.2, 10, [1,0,D,2] - #ok 8.1, 16, [ 8,D,1] - #ok 16.1, 16, [1,0,D,1] + ok 8.1, 10, [ 8,D,1] + ok 10.2, 10, [1,0,D,2] + #ok 8.1, 16, [ 8,D,1] + #ok 16.1, 16, [1,0,D,1] Give an integer value, it will automatically be converted to the base specified and given a fraction part set to zero. - check do |float, base, digits| - r = Radix::Float.new(float, base) - r.digits.assert == digits - end + check do |float, base, digits| + r = Radix::Float.new(float, base) + r.digits.assert == digits + end - ok 8, 2, [1,0,0,0,D,0] - ok 4, 2, [ 1,0,0,D,0] + ok 8, 2, [1,0,0,0,D,0] + ok 4, 2, [ 1,0,0,D,0] - ok 8, 10, [ 8,D,0] - ok 10, 10, [1,0,D,0] - ok 8, 16, [ 8,D,0] - ok 16, 16, [1,0,D,0] + ok 8, 10, [ 8,D,0] + ok 10, 10, [1,0,D,0] + ok 8, 16, [ 8,D,0] + ok 16, 16, [1,0,D,0] Given a float, the same will occur. - ok 8.0, 2, [1,0,0,0,D,0] - ok 4.0, 2, [ 1,0,0,D,0] + ok 8.0, 2, [1,0,0,0,D,0] + ok 4.0, 2, [ 1,0,0,D,0] - ok 8.0, 10, [ 8,D,0] - ok 10.0, 10, [1,0,D,0] - ok 8.0, 16, [ 8,D,0] - ok 16.0, 16, [1,0,D,0] + ok 8.0, 10, [ 8,D,0] + ok 10.0, 10, [1,0,D,0] + ok 8.0, 16, [ 8,D,0] + ok 16.0, 16, [1,0,D,0] Where as a String value is taken to already be in the base given. - ok "1000", 2, [1,0,0,0,D,0] - ok "100", 2, [ 1,0,0,D,0] + ok "1000", 2, [1,0,0,0,D,0] + ok "100", 2, [ 1,0,0,D,0] - ok "8", 10, [ 8,D,0] - ok "10", 10, [1,0,D,0] - ok "8", 16, [ 8,D,0] - ok "10", 16, [1,0,D,0] + ok "8", 10, [ 8,D,0] + ok "10", 10, [1,0,D,0] + ok "8", 16, [ 8,D,0] + ok "10", 16, [1,0,D,0] - ok "1000.0", 2, [1,0,0,0,D,0] - ok "100.0", 2, [ 1,0,0,D,0] + ok "1000.0", 2, [1,0,0,0,D,0] + ok "100.0", 2, [ 1,0,0,D,0] - ok "8.0", 10, [ 8,D,0] - ok "10.0", 10, [1,0,D,0] - ok "8.0", 16, [ 8,D,0] - ok "10.0", 16, [1,0,D,0] + ok "8.0", 10, [ 8,D,0] + ok "10.0", 10, [1,0,D,0] + ok "8.0", 16, [ 8,D,0] + ok "10.0", 16, [1,0,D,0] And an Array is also taken to be in the base given. - ok %w[1 0 0 0], 2, [1,0,0,0,D,0] - ok %w[ 1 0 0], 2, [ 1,0,0,D,0] + ok %w[1 0 0 0], 2, [1,0,0,0,D,0] + ok %w[ 1 0 0], 2, [ 1,0,0,D,0] - ok %w[ 8], 10, [ 8,D,0] - ok %w[1 0], 10, [1,0,D,0] - ok %w[ 8], 16, [ 8,D,0] - ok %w[1 0], 16, [1,0,D,0] + ok %w[ 8], 10, [ 8,D,0] + ok %w[1 0], 10, [1,0,D,0] + ok %w[ 8], 16, [ 8,D,0] + ok %w[1 0], 16, [1,0,D,0] Passing in an Array with a fraction part, either the DOT constant can be used, which is simply the symbol :'.', or the string '.' can be used. - ok %w[1 0 0 0 . 0], 2, [1,0,0,0,D,0] - ok %w[ 1 0 0 . 0], 2, [ 1,0,0,D,0] + ok %w[1 0 0 0 . 0], 2, [1,0,0,0,D,0] + ok %w[ 1 0 0 . 0], 2, [ 1,0,0,D,0] - ok %w[ 8 . 0], 10, [ 8,D,0] - ok %w[1 0 . 0], 10, [1,0,D,0] - ok %w[ 8 . 0], 16, [ 8,D,0] - ok %w[1 0 . 0], 16, [1,0,D,0] + ok %w[ 8 . 0], 10, [ 8,D,0] + ok %w[1 0 . 0], 10, [1,0,D,0] + ok %w[ 8 . 0], 16, [ 8,D,0] + ok %w[1 0 . 0], 16, [1,0,D,0] Integers can also be negative, rather than positive. In each case just prepend the value with a minus sign. - check do |float, base, digits| - r = Radix::Float.new(float, base) - r.digits.assert = digits - r.assert.negative? - end + check do |float, base, digits| + r = Radix::Float.new(float, base) + r.digits.assert = digits + r.assert.negative? + end - ok( -8, 2, ['-',1,0,0,0,D,0]) - ok( "-1000", 2, ['-',1,0,0,0,D,0]) - ok( %w[- 1 0 0 0], 2, ['-',1,0,0,0,D,0]) + ok( -8, 2, ['-',1,0,0,0,D,0]) + ok( "-1000", 2, ['-',1,0,0,0,D,0]) + ok( %w[- 1 0 0 0], 2, ['-',1,0,0,0,D,0]) If a value has a digit outside of the range of the base an ArgumentError will be raised. - expect ArgumentError do - Radix::Float.new('9', 2) - end + expect ArgumentError do + Radix::Float.new('9', 2) + end Radix provides a convenience extension method to Integer, String and Array called #b, to more easily initialize a Radix numeric object. The method simply passes the receiver on to `Radix::Integer#new`. - check do |float, base, digits| - r = float.b(base) - r.assert.is_a?(Radix::Float) - r.digits.assert = digits - end + check do |float, base, digits| + r = float.b(base) + r.assert.is_a?(Radix::Float) + r.digits.assert = digits + end - ok 8.0, 2, [1,0,0,0,D,0] - ok 4.0, 2, [ 1,0,0,D,0] + ok 8.0, 2, [1,0,0,0,D,0] + ok 4.0, 2, [ 1,0,0,D,0] - ok "1000.0", 2, [1,0,0,0,D,0] - ok "100.0", 2, [ 1,0,0,D,0] + ok "1000.0", 2, [1,0,0,0,D,0] + ok "100.0", 2, [ 1,0,0,D,0] - ok %w"1 0 0 0 . 0", 2, [1,0,0,0,D,0] - ok %w"1 0 0 . 0", 2, [ 1,0,0,D,0] + ok %w"1 0 0 0 . 0", 2, [1,0,0,0,D,0] + ok %w"1 0 0 . 0", 2, [ 1,0,0,D,0] -== Conversion +## Conversion Radix integers can ve converted to other bases with the #convert method. - b = "1000.0".b(2) - d = b.convert(10) - d.digits.assert == [8,D,0] + b = "1000.0".b(2) + d = b.convert(10) + d.digits.assert == [8,D,0] We can convert a Radix::Float to a regular base-10 Float with the #to_f method. - b = "1000.0".b(2) - d = b.to_f - d.assert == 8.0 + b = "1000.0".b(2) + d = b.to_f + d.assert == 8.0 We can convert a Radix::Float to a regular base-10 Integer with the #to_i method. - b = "1000.0".b(2) - d = b.to_i - d.assert == 8 + b = "1000.0".b(2) + d = b.to_i + d.assert == 8 -=== Equality +### Equality Radix extend the Integer, String and Array classes with the #b method which simplifies the creation of Radix::Float instances. The following return the equivalent instance of Radix::Float. - a = 8.0.b(2) - b = "1000.0".b(2) - c = [1,0,0,0,'.',0].b(2) + a = 8.0.b(2) + b = "1000.0".b(2) + c = [1,0,0,0,'.',0].b(2) - a.assert = b - b.assert = c - c.assert = a + a.assert = b + b.assert = c + c.assert = a - a.assert = 8.0 - b.assert = 8.0 - c.assert = 8.0 + a.assert = 8.0 + b.assert = 8.0 + c.assert = 8.0 More stringent equality can be had from #eql?, in which the other integer must be a Radix::Integer too. - a.assert.eql?(b) - a.refute.eql?(8.0) + a.assert.eql?(b) + a.refute.eql?(8.0) -== Operations +## Operations Radix::Float supports all the usual mathematical operators. -=== Addition +### Addition - check do |a, b, x| - (a + b).assert = x - end + check do |a, b, x| + (a + b).assert = x + end - ok "1000.0".b(2), "0010.0".b(2), "1010.0".b(2) - ok "1000.0".b(2), "2.0".b(8), "1010.0".b(2) - ok "1000.0".b(2), "2.0".b(8), "10.0".b(10) + ok "1000.0".b(2), "0010.0".b(2), "1010.0".b(2) + ok "1000.0".b(2), "2.0".b(8), "1010.0".b(2) + ok "1000.0".b(2), "2.0".b(8), "10.0".b(10) A more complex example. - x = "AZ42.0".b(62) + "54.0".b(10) - x.assert == "2518124.0".b(10) - x.assert == 2518124.0 + x = "AZ42.0".b(62) + "54.0".b(10) + x.assert == "2518124.0".b(10) + x.assert == 2518124.0 Adding negative integers will, of course, be akin to subtraction. - ok "1000.0".b(2), "-0010".b(2), "110.0".b(2) - ok "1000.0".b(2), "-2".b(8), "110.0".b(2) - ok "1000.0".b(2), "-2".b(8), "6.0".b(10) + ok "1000.0".b(2), "-0010".b(2), "110.0".b(2) + ok "1000.0".b(2), "-2".b(8), "110.0".b(2) + ok "1000.0".b(2), "-2".b(8), "6.0".b(10) - ok "-1000.0".b(2), "0010".b(2), "-110.0".b(2) - ok "-1000.0".b(2), "2".b(8), "-110.0".b(2) - ok "-1000.0".b(2), "2".b(8), "-6.0".b(10) + ok "-1000.0".b(2), "0010".b(2), "-110.0".b(2) + ok "-1000.0".b(2), "2".b(8), "-110.0".b(2) + ok "-1000.0".b(2), "2".b(8), "-6.0".b(10) - ok "-1000.0".b(2), "-0010".b(2), "-1010.0".b(2) - ok "-1000.0".b(2), "-2".b(8), "-1010.0".b(2) - ok "-1000.0".b(2), "-2".b(8), "-10.0".b(10) + ok "-1000.0".b(2), "-0010".b(2), "-1010.0".b(2) + ok "-1000.0".b(2), "-2".b(8), "-1010.0".b(2) + ok "-1000.0".b(2), "-2".b(8), "-10.0".b(10) -=== Subtraction +### Subtraction - check do |a, b, x| - (a - b).assert == x - end + check do |a, b, x| + (a - b).assert == x + end - ok "1000.0".b(2), "10".b(2), "110.0".b(2) - ok "1000.0".b(2), "2".b(8), "110.0".b(2) - ok "1000.0".b(2), "2".b(8), "6.0".b(8) - ok "1000.0".b(2), "2".b(8), "6.0".b(10) + ok "1000.0".b(2), "10".b(2), "110.0".b(2) + ok "1000.0".b(2), "2".b(8), "110.0".b(2) + ok "1000.0".b(2), "2".b(8), "6.0".b(8) + ok "1000.0".b(2), "2".b(8), "6.0".b(10) A more complex example. - x = "AZ42.0".b(62) - "54".b(10) - x.assert == "2518016.0".b(10) - x.assert == 2518016.0 + x = "AZ42.0".b(62) - "54".b(10) + x.assert == "2518016.0".b(10) + x.assert == 2518016.0 -=== Multiplication +### Multiplication - check do |a, b, x| - (a * b).assert = x - end + check do |a, b, x| + (a * b).assert = x + end - ok "1000.0".b(2), "10".b(2), "10000.0".b(2) - ok "1000.0".b(2), "2".b(8), "10000.0".b(2) - ok "1000.0".b(2), "2".b(8), "20.0".b(8) - ok "1000.0".b(2), "2".b(8), "16.0".b(10) + ok "1000.0".b(2), "10".b(2), "10000.0".b(2) + ok "1000.0".b(2), "2".b(8), "10000.0".b(2) + ok "1000.0".b(2), "2".b(8), "20.0".b(8) + ok "1000.0".b(2), "2".b(8), "16.0".b(10) A more complex example. - x = "Z42.0".b(62) * "4.0".b(10) - x.assert == "539160.0".b(10) - x.assert == 539160.0 + x = "Z42.0".b(62) * "4.0".b(10) + x.assert == "539160.0".b(10) + x.assert == 539160.0 -=== Division +### Division - check do |a, b, x| - (a / b).assert = x - end + check do |a, b, x| + (a / b).assert = x + end - ok "1000.0".b(2), "10".b(2), "100.0".b(2) - ok "1000.0".b(2), "2".b(8), "100.0".b(2) - ok "1000.0".b(2), "2".b(8), "4.0".b(8) - ok "1000.0".b(2), "2".b(8), "4.0".b(10) + ok "1000.0".b(2), "10".b(2), "100.0".b(2) + ok "1000.0".b(2), "2".b(8), "100.0".b(2) + ok "1000.0".b(2), "2".b(8), "4.0".b(8) + ok "1000.0".b(2), "2".b(8), "4.0".b(10) A more complex example. - x = "AZ40.0".b(62) / "62.0".b(10) - x.assert == "40614.0".b(10) - x.assert == 40614.0 + x = "AZ40.0".b(62) / "62.0".b(10) + x.assert == "40614.0".b(10) + x.assert == 40614.0 -=== Power +### Power - check do |a, b, x| - (a ** b).assert == x - end + check do |a, b, x| + (a ** b).assert == x + end - ok "1000.0".b(2), "10.0".b(2), 64.0 + ok "1000.0".b(2), "10.0".b(2), 64.0 -=== Modulo +### Modulo - check do |a, b, x| - (a % b).assert == x - end + check do |a, b, x| + (a % b).assert == x + end - ok "1000.0".b(2), "10".b(2), 0 - ok "1000.0".b(2), "11".b(2), 2 + ok "1000.0".b(2), "10".b(2), 0 + ok "1000.0".b(2), "11".b(2), 2 -== Coerce +## Coerce When a Radix::Integer is the operand in an operation against a regular Ruby Integer, the calculation should still work via #coerce. - check do |a, b, x| - (a + b).assert == x - end + check do |a, b, x| + (a + b).assert == x + end - ok 10.0, "10".b(2), "12".b(10) + ok 10.0, "10".b(2), "12".b(10) -= Radix Rational +# Radix Rational - require 'radix' + require 'radix' -== Initialization +## Initialization Radix::Rational's initializer takes a numerator and a denominator, either of which can be an Integer, Float, String or Array along witha an integer base. Give a integer value, it will automatically be converted to the base specified. - check do |num, dem, base, eqf| - r = Radix::Rational.new(num, dem, base) - r.assert == eqf - end + check do |num, dem, base, eqf| + r = Radix::Rational.new(num, dem, base) + r.assert == eqf + end - ok 1, 2, 2, 0.5 - ok 1, 1, 2, 1.0 + ok 1, 2, 2, 0.5 + ok 1, 1, 2, 1.0 - ok 8, 1, 10, 8.0 - ok 8, 5, 10, 1.6 - ok 8, 8, 10, 1.0 + ok 8, 1, 10, 8.0 + ok 8, 5, 10, 1.6 + ok 8, 8, 10, 1.0 - ok 10, 1, 10, 10.0 - ok 10, 2, 10, 5.0 - ok 10, 5, 10, 2.0 + ok 10, 1, 10, 10.0 + ok 10, 2, 10, 5.0 + ok 10, 5, 10, 2.0 - ok 8, 1, 16, 8.0 - ok 16, 1, 16, 16.0 + ok 8, 1, 16, 8.0 + ok 16, 1, 16, 16.0 -== Reduction +## Reduction - check do |a, x| - r = a.reduce - r.assert == x - end + check do |a, x| + r = a.reduce + r.assert == x + end - ok [10,5].br(10), [2,1].br(10) - ok [30,3].br(10), [10,1].br(10) + ok [10,5].br(10), [2,1].br(10) + ok [30,3].br(10), [10,1].br(10) -== Operations +## Operations -=== Addition +### Addition - check do |a, b, x| - r = a + b - r.assert == x - end + check do |a, b, x| + r = a + b + r.assert == x + end - ok [8,5].br(10), [1,2].br(10), [21,10].br(10) + ok [8,5].br(10), [1,2].br(10), [21,10].br(10) - ok [8,5].br(10), 1, [13,5].br(10) + ok [8,5].br(10), 1, [13,5].br(10) - ok [8,5].br(10), 0.5, [21,10].br(10) + ok [8,5].br(10), 0.5, [21,10].br(10) -=== Subtraction +### Subtraction - check do |a, b, x| - r = a - b - r.assert == x - end + check do |a, b, x| + r = a - b + r.assert == x + end - ok [8,5].br(10), [1,2].br(10), [11,10].br(10) + ok [8,5].br(10), [1,2].br(10), [11,10].br(10) -=== Multiplication +### Multiplication - check do |a, b, x| - r = a * b - r.assert == x - end + check do |a, b, x| + r = a * b + r.assert == x + end - ok [8,5].br(10), [1,2].br(10), [8,10].br(10) + ok [8,5].br(10), [1,2].br(10), [8,10].br(10) -=== Division +### Division - check do |a, b, x| - r = a / b - r.assert == x - end + check do |a, b, x| + r = a / b + r.assert == x + end - ok [8,5].br(10), [1,2].br(10), [16,5].br(10) + ok [8,5].br(10), [1,2].br(10), [16,5].br(10) -= Radix::Base +# Radix::Base The Radix::Base class is an encapsulatin of a numeric base. By creating an instance of Base one can convert numbers to and from other bases. - require 'radix/base' + require 'radix/base' -== Base Instance +## Base Instance First let's try something we all know, converting decimal to hexideciaml. To do this we setup the radix base objects for each base. - b10 = Radix::Base.new(Radix::BASE::B10) - b16 = Radix::Base.new(Radix::BASE::B16) + b10 = Radix::Base.new(Radix::BASE::B10) + b16 = Radix::Base.new(Radix::BASE::B16) Now we can covert from one base to the other. - b16.convert("16" , b10).should == "10" - b16.convert("160", b10).should == "A0" - b16.convert("255", b10).should == "FF" + b16.convert("16" , b10).should == "10" + b16.convert("160", b10).should == "A0" + b16.convert("255", b10).should == "FF" To confirm, lets convert from hexidecimal back to decimal. - b10.convert("10", b16).should == "16" - b10.convert("A0", b16).should == "160" - b10.convert("FF", b16).should == "255" + b10.convert("10", b16).should == "16" + b10.convert("A0", b16).should == "160" + b10.convert("FF", b16).should == "255" If we are happy with standard encodings then we can simply provide an integer base, rather than a Radix::Base object. - b10.convert("10", 16).should == "16" - b10.convert("A0", 16).should == "160" - b10.convert("FF", 16).should == "255" + b10.convert("10", 16).should == "16" + b10.convert("A0", 16).should == "160" + b10.convert("FF", 16).should == "255" Now let's try a more down to earth base, my favorite, senary, or base six. - b6 = Radix::Base.new(0..5) - b6.convert("39", 10).should == "103" + b6 = Radix::Base.new(0..5) + b6.convert("39", 10).should == "103" And the notations need not be in ASCII order. Odd alternate notations can be used as well. - b10 = Radix::Base.new([:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U]) - b10.convert("FF", 16) #=> "EYY" + b10 = Radix::Base.new([:Q, :W, :E, :R, :T, :Y, :U, :I, :O, :U]) + b10.convert("FF", 16) #=> "EYY" -== Encoding and Decoding +## Encoding and Decoding Radix::Base instances can also be used to encode and decode strings. - b16.encode("CHARLIE").should == "434841524C4945" - b16.decode("434841524C4945").should == "CHARLIE" + b16.encode("CHARLIE").should == "434841524C4945" + b16.decode("434841524C4945").should == "CHARLIE" -== Module Methods +## Module Methods For further convenience, Radix::base provides functions to convert to and from standard notations upto 62 without creating an instance of Radix::Base. - Radix.convert("10", 16, 10).should == "16" - Radix.convert("A0", 16, 10).should == "160" - Radix.convert("FF", 16, 10).should == "255" + Radix.convert("10", 16, 10).should == "16" + Radix.convert("A0", 16, 10).should == "160" + Radix.convert("FF", 16, 10).should == "255" Let's try that again with the maximum base supported. - Radix.convert( "62", 10, 62).should == "10" - Radix.convert("8814542", 10, 62).should == "az42" + Radix.convert( "62", 10, 62).should == "10" + Radix.convert("8814542", 10, 62).should == "az42" - Radix.convert( "10", 62, 10).should == "62" - Radix.convert( "az42", 62, 10).should == "8814542" + Radix.convert( "10", 62, 10).should == "62" + Radix.convert( "az42", 62, 10).should == "8814542" Finally, we will demonstrate how to convert bases larger than 62. These can only be represented as arrays since there are not enough latin characters to represent them. - Radix.convert_base([100, 10], 256, 10).should == [2, 5, 6, 1, 0] - Radix.convert_base([2, 5, 6, 1, 0], 10, 256).should == [100, 10] - Radix.convert_base([1, 0, 1, 0, 1], 2, 10).should == [2, 1] + Radix.convert_base([100, 10], 256, 10).should == [2, 5, 6, 1, 0] + Radix.convert_base([2, 5, 6, 1, 0], 10, 256).should == [100, 10] + Radix.convert_base([1, 0, 1, 0, 1], 2, 10).should == [2, 1] + + +# Zero becomes empty string (#4) + +Example of the issue: + + 0.b(10).to_s #=> "" + +I would expect "0" as a result. + + 0.b(10).to_s #=> "0" + +Okay, lets make sure this works for Floats. + + 0.0.b(10).to_s #=> "0.0" + +And Rationals too. + + [0,1].br(10).to_s #=> "0/1"