Last active
April 19, 2018 05:14
-
-
Save komasaru/5334577 to your computer and use it in GitHub Desktop.
Ruby script to compute big-digit values.(v2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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