Last active
March 27, 2018 13:30
-
-
Save komasaru/77be09a274175db1797536dae2424a72 to your computer and use it in GitHub Desktop.
Python script to compute big-digit floats.
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/python3.6 | |
""" | |
Comutation between two big-digit floats | |
""" | |
import random | |
import sys | |
import traceback | |
class AddBigFloat: | |
D_MAX = 1001 # Number of significant digits | |
def __init__(self): | |
# Should be A > C | |
self.a, self.b, self.c = [], [], [] | |
self.a.append(random.randrange(self.D_MAX - 1) + 1) | |
self.b.append(random.randrange(self.D_MAX - 1) + 1) | |
self.c.append(self.a[0] - random.randrange(self.a[0]) - 1) | |
self.a += [random.randrange(10)for _ in range(self.D_MAX - 1)] | |
self.b += [random.randrange(10)for _ in range(self.D_MAX - 1)] | |
self.c += [random.randrange(10)for _ in range(self.D_MAX - 1)] | |
def compute(self): | |
""" | |
Computation | |
""" | |
try: | |
print("A =") | |
self.__fdisp(self.a) | |
print("B =") | |
self.__fdisp(self.b) | |
print("C =") | |
self.__fdisp(self.c) | |
print("A + B =") | |
self.__fdisp(self.__fadd(self.a, self.b, 1)) | |
print("A - C =") | |
self.__fdisp(self.__fadd(self.a, self.c, -1)) | |
except Exception as e: | |
raise | |
def __add(self, a, b, flag): | |
""" Addition or subtraction between two integers | |
:param list a | |
:param list b | |
:param int flag | |
:return list z | |
""" | |
try: | |
if flag >= 0: | |
z = [a[i] + b[i] for i in range(len(a))] | |
else: | |
z = [a[i] - b[i] for i in range(len(a))] | |
return self.__norm(z) | |
except Exception as e: | |
raise | |
def __fadd(self, a, b, flag): | |
""" Addition or subtraction between two floats | |
:param list a | |
:param list b | |
:param int flag | |
:return list z | |
""" | |
z = [] | |
try: | |
if a[0] >= b[0]: | |
k = a[0] - b[0] | |
z = a[:(k + 1)] | |
z += self.__add(a[(k + 1):], b[1:(len(a) + k)], flag) | |
else: | |
z.append(b[0]) | |
k = b[0] - a[0] | |
if flag >= 0: | |
z += b[1:(k + 1)] | |
else: | |
z += [-b[i] for i in range(1, k + 1)] | |
z += self.__add(a[1:(-k)], b[(k + 1):], flag) | |
return self.__fnorm([z[0]] + self.__norm(z[1:])) | |
except Exception as e: | |
raise | |
def __norm(self, a): | |
""" Normalization of a integer | |
:param list a | |
:return list a | |
""" | |
cr = 0 | |
try: | |
for i in range(len(a) - 1, 0, -1): | |
cr = int(a[i] / 10) | |
a[i] -= cr * 10 | |
a[i - 1] += cr | |
for i in range(len(a) - 1, 0, -1): | |
if a[i] < 0: | |
a[i - 1] -= 1 | |
a[i] += 10 | |
return a | |
except Exception as e: | |
raise | |
def __fnorm(self, a): | |
""" Normalization of a float | |
:param list a | |
:return list a | |
""" | |
k = 0 | |
try: | |
if a[1] >= 10: | |
for i in range(len(a) - 2, 1, -1): | |
a[i + 1] = a[i] | |
a[2] = a[1] % 10 | |
a[1] = int(a[1] / 10) | |
a[0] += 1 | |
exp = a[0] | |
for i in range(1, len(a) + 1): | |
if a[i] != 0: | |
k = i - 1 | |
break | |
for i in range(1, len(a) - k): | |
a[i] = a[i + k] | |
for i in range(len(a) - k, len(a)): | |
a[i] = 0 | |
a[0] = exp - k | |
return a | |
except Exception as e: | |
raise | |
def __fdisp(self, s): | |
""" Display | |
:param list s | |
""" | |
try: | |
if s[1] < 0: | |
print("ANS. < 0\nPlease retry!") | |
sys.exit() | |
print("0.", end="") | |
for i in range(1, len(s)): | |
print(s[i], end="") | |
if i % 10 == 0: | |
print(" ", end="") | |
if i % 50 == 0: | |
print("\n ", end="") | |
if s[0] < 0: | |
print(" * 10^({})".format(s[0])) | |
else: | |
print(" * 10^{}".format(s[0])) | |
print() | |
except Exception as e: | |
raise | |
if __name__ == '__main__': | |
try: | |
obj = AddBigFloat() | |
obj.compute() | |
except Exception as e: | |
traceback.print_exc() | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment