@@ -48,6 +48,27 @@ def __init__(
48
48
if force_mantissa is not None
49
49
else mantissa_list [self .precision ]
50
50
)
51
+ self .output : dict = {
52
+ "number" : "" ,
53
+ "edge_case" : False ,
54
+ "sign_bit" : "" ,
55
+ "exponent_bits" : "" ,
56
+ "mantissa_bits" : "" ,
57
+ "total_bits" : "" ,
58
+ "sign" : "" ,
59
+ "scale" : "" ,
60
+ "scaled_number" : "" ,
61
+ "scaled_number_in_binary" : "" ,
62
+ "unable_to_scale" : False ,
63
+ "bias" : "" ,
64
+ "exponent" : "" ,
65
+ "mantissa" : "" ,
66
+ "result" : "" ,
67
+ "hexadecimal" : "" ,
68
+ "hexadecimal_parts" : [],
69
+ "converted_number" : "" ,
70
+ "error" : "" ,
71
+ }
51
72
self .__bias : int = 2 ** (self .__exponent - 1 ) - 1
52
73
self .__edge_case : str = None
53
74
self .number : Decimal = self .validate_number (number )
@@ -69,34 +90,51 @@ def validate_number(self, number: str) -> Decimal:
69
90
if Decimal (number ).is_infinite ():
70
91
if Decimal (number ) > 0 :
71
92
# +inf: 0 11111111 00000000000000000000000
72
- self .__edge_case = f"0 { '1' * self .__exponent } { '0' * self .__mantissa } "
93
+ self .sign = "0"
94
+ self .exponent = f"{ '1' * self .__exponent } "
95
+ self .mantissa = f"{ '0' * self .__mantissa } "
96
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
73
97
return Decimal ("Infinity" )
74
98
# -inf: 1 11111111 00000000000000000000000
75
- self .__edge_case = f"1 { '1' * self .__exponent } { '0' * self .__mantissa } "
99
+ self .sign = "1"
100
+ self .exponent = f"{ '1' * self .__exponent } "
101
+ self .mantissa = f"{ '0' * self .__mantissa } "
102
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
76
103
return Decimal ("-Infinity" )
77
104
if Decimal (number ).is_nan () and Decimal (number ).is_snan ():
78
105
# snan: 0 11111111 00000000000000000000001
79
- self .__edge_case = (
80
- f"0 { '1' * self .__exponent } { '0' * (self .__mantissa - 1 )} 1"
81
- )
106
+ self .sign = "0"
107
+ self .exponent = f"{ '1' * self .__exponent } "
108
+ self .mantissa = f"{ '0' * (self .__mantissa - 1 )} 1"
109
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
82
110
return Decimal ("NaN" )
83
111
if Decimal (number ).is_nan () and Decimal (number ).is_qnan ():
84
112
# qnan: 0 11111111 10000000000000000000000
85
- self .__edge_case = (
86
- f"0 { '1' * self .__exponent } 1{ '0' * (self .__mantissa - 1 )} "
87
- )
113
+ self .sign = "0"
114
+ self .exponent = f"{ '1' * self .__exponent } "
115
+ self .mantissa = f"1{ '0' * (self .__mantissa - 1 )} "
116
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
88
117
return Decimal ("NaN" )
89
118
if not number == number :
90
119
# nan: 0 11111111 11111111111111111111111
91
- self .__edge_case = f"0 { '1' * self .__exponent } { '1' * self .__mantissa } "
120
+ self .sign = "0"
121
+ self .exponent = f"{ '1' * self .__exponent } "
122
+ self .mantissa = f"{ '1' * self .__mantissa } "
123
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
92
124
return Decimal ("NaN" )
93
125
if Decimal (number ) == 0 :
94
126
if Decimal (number ).is_signed ():
95
127
# -0: 1 00000000 00000000000000000000000
96
- self .__edge_case = f"1 { '0' * self .__exponent } { '0' * self .__mantissa } "
128
+ self .sign = "1"
129
+ self .exponent = f"{ '0' * self .__exponent } "
130
+ self .mantissa = f"{ '0' * self .__mantissa } "
131
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
97
132
else :
98
133
# +0: 0 00000000 00000000000000000000000
99
- self .__edge_case = f"0 { '0' * self .__exponent } { '0' * self .__mantissa } "
134
+ self .sign = "0"
135
+ self .exponent = f"{ '0' * self .__exponent } "
136
+ self .mantissa = f"{ '0' * self .__mantissa } "
137
+ self .__edge_case = f"{ self .sign } { self .exponent } { self .mantissa } "
100
138
return Decimal ("0" )
101
139
if isinstance (number , int ):
102
140
number = f"{ number } .0"
@@ -143,14 +181,11 @@ def scale_up_to_integer(number: Decimal, base: int) -> (int, int):
143
181
144
182
def find_exponent (self ) -> str :
145
183
exponent = len (self .binary ) - 1 + self .__bias - self .__scale
146
- # fill with leading zeros if necessary
147
184
return f"{ exponent :0{self .__exponent }b} "
148
185
149
186
def find_mantissa (self ) -> str :
150
- # fill with trailing zeros if necessary
151
187
mantissa = f"{ self .binary [1 :]:<0{self .__mantissa }} "
152
188
if len (mantissa ) > self .__mantissa :
153
- # round up if mantissa is too long
154
189
mantissa = f"{ mantissa [: self .__mantissa - 1 ]} 1"
155
190
return mantissa
156
191
@@ -159,8 +194,9 @@ def __str__(self) -> str:
159
194
return self .__edge_case
160
195
return f"{ self .sign } { self .exponent } { self .mantissa } "
161
196
162
- def hex (self ) -> str :
197
+ def hex (self ) -> ( str , list [ str ]) :
163
198
h = ""
199
+ hex_parts = []
164
200
s = str (self ).replace (" " , "" )
165
201
if len (s ) % 4 != 0 :
166
202
next_multiple = (len (s ) // 4 + 1 ) * 4
@@ -171,32 +207,48 @@ def hex(self) -> str:
171
207
si = 0
172
208
for j in range (4 ):
173
209
si += int (ss [j ]) * (2 ** (3 - j ))
210
+ hex_parts .append (ss )
174
211
sh = hex (si )
175
212
h += sh [2 ]
176
- return h .upper ()
213
+ return h .upper (), hex_parts
177
214
178
215
def json (self ) -> dict :
179
- return {
180
- "exponent-bits" : self .__exponent ,
181
- "mantissa-bits" : self .__mantissa ,
182
- "bias" : self .__bias ,
183
- "sign" : self .sign ,
184
- "exponent" : self .exponent ,
185
- "mantissa" : self .mantissa ,
186
- "binary" : self .binary ,
187
- "binary_output" : self .binary_output ,
188
- "hex" : self .hex (),
189
- "up scaled number" : self .number ,
190
- "scale" : self .__scale ,
191
- "number" : self .number / (2 ** self .__scale ),
192
- "converted_number" : self .converted_number ,
193
- "error" : self .error ,
194
- }
216
+ return self .produce_output ()
195
217
196
218
def __repr__ (self ) -> str :
197
219
return self .__str__ ()
198
220
221
+ def produce_output (self ) -> dict :
222
+ self .output ["number" ] = self .original_number
223
+ self .output ["sign_bit" ] = "1"
224
+ self .output ["exponent_bits" ] = self .__exponent
225
+ self .output ["mantissa_bits" ] = self .__mantissa
226
+ self .output ["total_bits" ] = 1 + self .__exponent + self .__mantissa
227
+ self .output ["sign" ] = self .sign
228
+ self .output ["exponent" ] = self .exponent
229
+ self .output ["mantissa" ] = self .mantissa
230
+ self .output ["bias" ] = self .__bias
231
+ self .output ["hexadecimal" ], self .output ["hexadecimal_parts" ] = self .hex ()
232
+ self .output ["result" ] = self .__str__ ()
233
+ if self .__edge_case is None :
234
+ self .output ["scale" ] = self .__scale
235
+ self .output ["scaled_number" ] = self .number
236
+ self .output ["scaled_number_in_binary" ] = self .binary
237
+ (
238
+ self .output ["converted_number" ],
239
+ self .output ["error" ],
240
+ ) = self .back_to_decimal_from_bits ()
241
+ else :
242
+ self .output ["edge_case" ] = True
243
+ return self .output
244
+
199
245
def back_to_decimal_from_bits (self ) -> (Decimal , Decimal ):
246
+ """
247
+ Returns
248
+ -------
249
+ Decimal
250
+ Decimal representation of the number
251
+ """
200
252
sign , exponent , mantissa = self .__str__ ().split (" " )
201
253
sign = (- 1 ) ** int (sign )
202
254
exponent = int (exponent , 2 ) - self .__bias
@@ -397,3 +449,5 @@ def octuple(x: str) -> IEEE754:
397
449
x = 8.7
398
450
a = IEEE754 (x , 1 )
399
451
print (f"{ x } is converted as { a .converted_number } ± { a .error } " )
452
+ # you can get the full output as a dictionary with produce_output()
453
+ print (a .produce_output ())
0 commit comments