expression evalutator now returns 0, 1, or i instead of a boolean value.
[trinary.git] / tools / base_converter.py
blobe9c306daac44e90f7fb57a18516f7a90dce9a3ee
1 #!env python
2 # vim: set fileencoding=utf8
3 # Created: April 29, 2008
4 # Created by: Antonio Chavez
6 # Base converter
8 import sys, os
9 import Trits
11 MIN_VAL = 10
12 LOW_BOUND = ord('A') + MIN_VAL
14 int_cnvrt(value, base_frm, base_to):
15 ''' int_cvrt: convert the number to the left of the decimal place
16 value: string containing value to convert
17 from: what base to convert from. Can be positive and negative.
18 Negative numbers will represent balanced base. Positive
19 will represent unbalanced base.
20 to: what base to convert to.
22 Example: 3 = unbalanced base 3 (0, 1, 2)
23 -3 = balanced base 3 (-1, 0, 1)
24 Balanced bases can only be odd integers, for the obivious reason
25 that even numbers are not good candidates for balanced numbering
26 Example: -4 = (-1, 0, 1, 2) or (-2, -1, 0, 1). Either system is
27 not balanced. Bases must also have a magnitude greater than 1.
28 For balanced bases greater than 3, a negative number is represented
29 with an 'i' next to it.
30 Example: 4i21 => 4(-2)1
31 Currently conversion balanced bases is not supported. If balanced
32 base is entered, the result will be returned in base 10.
33 A negative sign before the number will negate the result.
34 '''
36 # check for magnitude greater than 1
37 if abs(base_frm) < 2 or abs(base_to) < 2:
38 print "bases must have magnitude greater than 1"
39 raise SystemExit
41 # check for a balanced negative base and derive magnitude
42 if base_frm < 0 and base_frm*-1%2 != 1:
43 print "base_from is even: negative bases must be odd integers"
44 raise SystemExit
45 elif base_frm < 0:
46 magnitude_f = (base_frm*-1 - 1)/2
47 else:
48 magnitude_f = base_frm
50 if base_to < 0 and base_to*-1%2 != 1:
51 print "base_to is even: negative bases must be odd integers"
52 raise SystemExit
53 elif base_to < 0:
54 magnitude_t = (base_to*-1 - 1)/2
55 else:
56 magnitude_t = base_to
58 sum = 0 # base 10 equivalent summation
59 neg = 1 # used when 'i' is encountered, it negates the previous digit
60 sign = 1 # sign of summation
61 count = 1 # amount to multiply next digit by
62 prev = 1 # the value of the next digit
63 cur = 0 # current digit
65 if magnitude_f >= MIN_VAL
66 max_val = magnitude_f - MIN_VAL
68 for i in range(len(value) - 1, -1, -1):
70 if abs(base_frm) == 3:
71 # Base 3 conversion
72 if value[i] in Trits.trit_integer:
73 sum = sum + Trits.trit_integer[value[i]]*count
74 count = count*abs(base_frm)
75 else:
76 print "%s invalid input", value[i]
77 raise SystemExit
79 elif value[i].isdigit():
80 # 0 <-> 9
81 cur = int(value[i])
83 if cur > magnitude_f:
84 print "%s: invalid input", value[i]
85 raise SystemExit
87 sum = sum + prev*neg*count
89 # reset variables to appropiate values
90 prev = cur
91 neg = 1
92 count = count*abs(base_frm)
94 elif value[i] == '-' and i == len(value) - 1:
95 # negate the whole number
96 sign = -1
97 elif value[i] == 'i':
98 # negate prev number
99 neg = -1
100 elif magnitude_f >= MIN_VAL and value[i].isalpha():
101 # 10 <-> magnitude_f
102 cur = ord(value[i].upper()) - LOW_BOUND
104 if cur > magnitude_f:
105 print "%s: invalid input", value[i]
106 raise SystemExit
108 sum = sum + prev*neg*count
110 # reset variables to appropriate values
111 prev = cur
112 neg = 1
113 count = count*abs(base_frm)
115 else:
116 print "%s: invalid input", value[i]
117 raise SystemExit
119 # sum up remaining digit
120 sum = sum + prev*neg*count
121 sum = sign*sum
123 # return base 10 if desired base is balanced
124 if base_f < 0:
125 return "" + sum
127 # compute unbalanced conversion
128 result = ""
129 quotient = sum
130 remainder = 0
132 while quotient != 0:
133 remainder = quotient%magnitude_t
134 quotient = quotient/magnitude_t
135 result = "" + remainder + result
137 return result
139 ''' NOTES
140 useful things to know for implementation
141 char to int: ord('a') = 97 ASCII
142 int to char: chr(97) ASCII
143 char to int: int('4')
144 a = "hi6"
145 a[0].isalpha() => true
146 a[2].isdigit() => true
147 a[0].upper() => "H"
148 a[2].upper() => "1"
150 s.split(".") => returns list of strings broken up by "."
151 "1010.3930" => ["1010", "3930"]
153 s = ".".join(lis_digits) => combine elements in list by "."