[前][次][番号順一覧][スレッド一覧]

ruby-changes:3738

From: ko1@a...
Date: Fri, 25 Jan 2008 13:42:47 +0900 (JST)
Subject: [ruby-changes:3738] akr - Ruby:r15227 (trunk): combinational tests for printf.

akr	2008-01-25 13:42:36 +0900 (Fri, 25 Jan 2008)

  New Revision: 15227

  Added files:
    trunk/test/ruby/test_sprintf_comb.rb

  Log:
    combinational tests for printf.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_sprintf_comb.rb?revision=15227&view=markup
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_sprintf_comb.rb?r1=15227&r2=15226&diff_format=u

Index: test/ruby/test_sprintf_comb.rb
===================================================================
--- test/ruby/test_sprintf_comb.rb	(revision 0)
+++ test/ruby/test_sprintf_comb.rb	(revision 15227)
@@ -0,0 +1,300 @@
+require 'test/unit'
+
+class TestSprintfComb < Test::Unit::TestCase
+  VS = [
+    #-0x1000000000000000000000000000000000000000000000002,
+    #-0x1000000000000000000000000000000000000000000000001,
+    #-0x1000000000000000000000000000000000000000000000000,
+    #-0xffffffffffffffffffffffffffffffffffffffffffffffff,
+    #-0x1000000000000000000000002,
+    #-0x1000000000000000000000001,
+    #-0x1000000000000000000000000,
+    #-0xffffffffffffffffffffffff,
+    -0x10000000000000002,
+    -0x10000000000000001,
+    -0x10000000000000000,
+    -0xffffffffffffffff,
+    -0x4000000000000002,
+    -0x4000000000000001,
+    -0x4000000000000000,
+    -0x3fffffffffffffff,
+    -0x100000002,
+    -0x100000001,
+    -0x100000000,
+    -0xffffffff,
+    #-0xc717a08d, # 0xc717a08d * 0x524b2245 = 0x4000000000000001
+    -0x80000002,
+    -0x80000001,
+    -0x80000000,
+    -0x7fffffff,
+    #-0x524b2245,
+    -0x40000002,
+    -0x40000001,
+    -0x40000000,
+    -0x3fffffff,
+    #-0x10002,
+    #-0x10001,
+    #-0x10000,
+    #-0xffff,
+    #-0x8101, # 0x8101 * 0x7f01 = 0x40000001
+    #-0x8002,
+    #-0x8001,
+    #-0x8000,
+    #-0x7fff,
+    #-0x7f01,
+    #-65,
+    #-64,
+    #-63,
+    #-62,
+    #-33,
+    #-32,
+    #-31,
+    #-30,
+    -3,
+    -2,
+    -1,
+    0,
+    1,
+    2,
+    3,
+    #30,
+    #31,
+    #32,
+    #33,
+    #62,
+    #63,
+    #64,
+    #65,
+    #0x7f01,
+    #0x7ffe,
+    #0x7fff,
+    #0x8000,
+    #0x8001,
+    #0x8101,
+    #0xfffe,
+    #0xffff,
+    #0x10000,
+    #0x10001,
+    0x3ffffffe,
+    0x3fffffff,
+    0x40000000,
+    0x40000001,
+    #0x524b2245,
+    0x7ffffffe,
+    0x7fffffff,
+    0x80000000,
+    0x80000001,
+    #0xc717a08d,
+    0xfffffffe,
+    0xffffffff,
+    0x100000000,
+    0x100000001,
+    0x3ffffffffffffffe,
+    0x3fffffffffffffff,
+    0x4000000000000000,
+    0x4000000000000001,
+    0xfffffffffffffffe,
+    0xffffffffffffffff,
+    0x10000000000000000,
+    0x10000000000000001,
+    #0xffffffffffffffffffffffff,
+    #0x1000000000000000000000000,
+    #0x1000000000000000000000001,
+    #0xffffffffffffffffffffffffffffffffffffffffffffffff,
+    #0x1000000000000000000000000000000000000000000000000,
+    #0x1000000000000000000000000000000000000000000000001
+  ]
+  VS.reverse!
+
+  def combination(*args)
+    if args.empty?
+      yield []
+    else
+      arg = args.shift
+      arg.each {|v|
+        combination(*args) {|vs|
+          yield [v, *vs]
+        }
+      }
+    end
+  end
+
+  def emu(format, v)
+    /\A%( )?(\#)?(\+)?(-)?(0)?(\d+)?(?:\.(\d+))?(.)\z/ =~ format
+    sp = $1
+    hs = $2
+    pl = $3
+    mi = $4
+    zr = $5
+    width = $6
+    precision = $7
+    type = $8
+    width = width.to_i if width
+    precision = precision.to_i if precision
+    prefix = ''
+
+    zr = nil if precision
+
+    zr = nil if mi && zr
+
+    case type
+    when 'b'
+      radix = 2
+      digitmap = {0 => '0', 1 => '1'}
+      complement = !pl && !sp
+      prefix = '0b' if hs
+    when 'd'
+      radix = 10
+      digitmap = {}
+      10.times {|i| digitmap[i] = i.to_s }
+      complement = false
+    when 'o'
+      radix = 8
+      digitmap = {}
+      8.times {|i| digitmap[i] = i.to_s }
+      complement = !pl && !sp
+    when 'X'
+      radix = 16
+      digitmap = {}
+      16.times {|i| digitmap[i] = i.to_s(16).upcase }
+      complement = !pl && !sp
+      prefix = '0X' if hs
+    when 'x'
+      radix = 16
+      digitmap = {}
+      16.times {|i| digitmap[i] = i.to_s(16) }
+      complement = !pl && !sp
+      prefix = '0x' if hs
+    else
+      raise "unexpected type: #{type.inspect}"
+    end
+
+    digits = []
+    abs = v.abs
+    sign = ''
+    while 0 < abs
+      digits << (abs % radix)
+      abs /= radix
+    end
+
+    if v < 0
+      if complement
+        digits.map! {|d| radix-1 - d }
+        carry = 1
+        digits.each_index {|i|
+          digits[i] += carry
+          carry = 0
+          if radix <= digits[i]
+            digits[i] -= radix
+            carry = 1
+          end
+        }
+        if digits.last != radix-1
+          digits << (radix-1)
+        end
+        sign = '..'
+      else
+        sign = '-'
+      end
+    else
+      if pl
+        sign = '+'
+      elsif sp
+        sign = ' '
+      end
+    end
+
+    dlen = digits.length
+    dlen += 2 if sign == '..'
+
+    if v < 0 && complement
+      d = radix - 1
+    else
+      d = 0
+    end
+    if precision
+      if dlen < precision
+        (precision - dlen).times {
+          digits << d
+        }
+      end
+    else
+      if dlen == 0
+        digits << d
+      end
+    end
+    if type == 'o' && hs
+      if digits.empty? || digits.last != d
+        digits << d
+      end
+    end
+
+    digits.reverse!
+
+    str = digits.map {|d| digitmap[d] }.join
+
+    pad = ''
+    nlen = prefix.length + sign.length + str.length
+    if width && nlen < width
+      len = width - nlen
+      if zr
+        if complement && v < 0
+          pad = digitmap[radix-1] * len
+        else
+          pad = '0' * len
+        end
+      else
+        pad = ' ' * len
+      end
+    end
+
+    if / / =~ pad
+      if sign == '..'
+        str = prefix + sign + str
+      else
+        str = sign + prefix + str
+      end
+      if mi
+        str = str + pad
+      else
+        str = pad + str
+      end
+    else
+      if sign == '..'
+        str = prefix + sign + pad + str
+      else
+        str = sign + prefix + pad + str
+      end
+    end
+
+    str
+  end
+
+  def test_format
+    combination(
+        %w[b d o X x],
+        [nil, 0, 5, 20],
+        [nil, 0, 8, 20],
+        ['', ' '],
+        ['', '#'],
+        ['', '+'],
+        ['', '-'],
+        ['', '0']) {|type, width, precision, sp, hs, pl, mi, zr|
+      if precision
+        precision = ".#{precision}"
+      end
+      format = "%#{sp}#{hs}#{pl}#{mi}#{zr}#{width}#{precision}#{type}"
+      VS.each {|v|
+        r = sprintf format, v
+        e = emu format, v
+        if true
+          assert_equal(e, r, "sprintf(#{format.dump}, #{v})")
+        else
+          if e != r
+            puts "#{e.dump}\t#{r.dump}\tsprintf(#{format.dump}, #{v})"
+          end
+        end
+      }
+    }
+  end
+end

Property changes on: test/ruby/test_sprintf_comb.rb
___________________________________________________________________
Name: svn:eol-style
   + LF


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]