Skip to content

Instantly share code, notes, and snippets.

@komasaru
Last active April 19, 2018 05:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komasaru/5334577 to your computer and use it in GitHub Desktop.
Save komasaru/5334577 to your computer and use it in GitHub Desktop.
Ruby script to compute big-digit values.(v2)
#! /usr/local/bin/ruby
#*********************************************
# 多桁計算
# ( 符号は考慮しない。)
#*********************************************
#
class CalcBigDigits
N_A = 1000 # 計算桁数 ( 被加減乗除数 )
N_B = 996 # 計算桁数 ( 加減乗除数 )
LIMIT = 4 # 配列1つあたり桁数
SIZE_A = (N_A - 1) / LIMIT + 1 # 配列サイズ
SIZE_B = (N_B - 1) / LIMIT + 1 # 配列サイズ
def initialize
# 使用する被加減乗除数・加減乗除数を設定(テストなので乱数を使用)
@a_0 = (0...SIZE_A).map { rand(10 ** LIMIT) }
@b_0 = (0...SIZE_B).map { rand(10 ** LIMIT) }
@c_0 = rand(10 ** LIMIT)
puts "A ="; display(@a_0)
puts "B ="; display(@b_0)
puts "C =\n%04d\n\n" % @c_0
end
# 計算 ( 加算 )
def calc_add
puts "A + B ="
display(long_add(@a_0, @b_0))
rescue => e
raise
end
# 計算 ( 減算 )
def calc_sub
puts "A - B ="
display(long_sub(@a_0, @b_0))
rescue => e
raise
end
# 計算 ( 乗算 )
def calc_mul
puts "A * C ="
display(long_mul(@a_0, @c_0))
rescue => e
raise
end
# 計算 ( 除算 )
def calc_div
puts "A / C ="
display(long_div(@a_0, @c_0))
rescue => e
raise
end
private
# ロング + ロング
def long_add(a, b)
z = Array.new([a.size, b.size].max + 1, 0)
0.upto(a.size - 1) { |i| z[i] = a[i] }
0.upto(b.size - 1) do |i|
z[i] += b[i]
if z[i] >= 10 ** LIMIT
z[i] -= 10 ** LIMIT
z[i + 1] += 1
end
end
return z
rescue => e
raise
end
# ロング - ロング
def long_sub(a, b)
z = Array.new([a.size, b.size].max, 0)
0.upto(a.size - 1) { |i| z[i] = a[i] }
0.upto(b.size - 1) do |i|
z[i] -= b[i]
if z[i] < 0
z[i] += 10 ** LIMIT
z[i + 1] -= 1
end
end
return z
rescue => e
raise
end
# ロング * ショート
def long_mul(a, c)
z = Array.new(a.size + 1, 0)
0.upto(a.size - 1) do |i|
z[i] += a[i] * c
if z[i] >= 10 ** LIMIT
z[i + 1] += z[i] / 10 ** LIMIT
z[i] %= 10 ** LIMIT
end
end
return z
rescue => e
raise
end
# ロング / ショート
def long_div(a, c)
z = Array.new(a.size, 0)
(a.size - 1).downto(0) do |i|
z[i] += a[i] / c
a[i - 1] += (a[i] % c) * 10 ** LIMIT if i > 0
end
return z
rescue => e
raise
end
# 結果出力
def display(s)
size = s.size
# 最上位で繰り上がりが無かった場合の処置
size -= 1 if (s[size - 1] == 0)
# 1行に配列10個分出力
(size - 1).downto(0) do |i|
printf("%04d ", s[i])
puts if (size - i) % 10 == 0 && i != 0
end
puts "\n\n"
rescue => e
raise
end
end
if __FILE__ == $0
begin
obj = CalcBigDigits.new # 計算クラスインスタンス化
obj.calc_add # 計算 ( 加算 )
obj.calc_sub # 計算 ( 減算 )
obj.calc_mul # 計算 ( 乗算 )
obj.calc_div # 計算 ( 除算 )
rescue => e
$stderr.puts "[#{e.class}] #{e.message}"
e.backtrace.each{ |tr| $stderr.puts "\t#{tr}" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment