|
| 1 | +# Copyright 2025 Matt Borland |
| 2 | +# Distributed under the Boost Software License, Version 1.0. |
| 3 | +# https://www.boost.org/LICENSE_1_0.txt |
| 4 | + |
| 5 | +import sys |
| 6 | +import os |
| 7 | +sys.path.insert(0, os.path.dirname(__file__)) |
| 8 | + |
| 9 | +from generate_string import generate_string |
| 10 | + |
| 11 | +def decode_decimal32(bits): |
| 12 | + sign = bits & 2147483648 != 0 |
| 13 | + isnan = False |
| 14 | + |
| 15 | + if bits & 2013265920 == 2013265920: |
| 16 | + |
| 17 | + if bits & 2113929216 == 2113929216: |
| 18 | + result = "-SNAN" if sign else "SNAN" |
| 19 | + isnan = True |
| 20 | + elif bits & 2080374784 == 2080374784: |
| 21 | + result = "-SNAN" if sign else "QNAN" |
| 22 | + isnan = True |
| 23 | + elif bits & 2080374784 == 2013265920: |
| 24 | + result = "-INF" if sign else "INF" |
| 25 | + else: |
| 26 | + raise ValueError("Unknown Finite Value") |
| 27 | + |
| 28 | + if isnan: |
| 29 | + payload = bits & 8388607 |
| 30 | + if payload > 0: |
| 31 | + result += '(' + str(payload) + ')' |
| 32 | + |
| 33 | + else: |
| 34 | + # See decimal32_t::to_components() |
| 35 | + d32_comb_11_mask = 1610612736 |
| 36 | + if bits & d32_comb_11_mask == d32_comb_11_mask: |
| 37 | + implied_bit = 8388608 |
| 38 | + significand = implied_bit | (bits & 2097151) |
| 39 | + exp = (bits & 534773760) >> 21 |
| 40 | + else: |
| 41 | + significand = bits & 8388607 |
| 42 | + exp = (bits & 2139095040) >> 23 |
| 43 | + |
| 44 | + exp -= 101 # Bias Value |
| 45 | + |
| 46 | + result = generate_string(significand, exp, sign) |
| 47 | + |
| 48 | + return result |
| 49 | + |
| 50 | +def decode_decimal64(bits): |
| 51 | + sign = bits & 9223372036854775808 != 0 |
| 52 | + isnan = False |
| 53 | + |
| 54 | + if bits & 8646911284551352320 == 8646911284551352320: |
| 55 | + |
| 56 | + if bits & 9079256848778919936 == 9079256848778919936: |
| 57 | + result = "-SNAN" if sign else "SNAN" |
| 58 | + isnan = True |
| 59 | + elif bits & 8935141660703064064 == 8935141660703064064: |
| 60 | + result = "-SNAN" if sign else "QNAN" |
| 61 | + isnan = True |
| 62 | + elif bits & 8935141660703064064 == 8646911284551352320: |
| 63 | + result = "-INF" if sign else "INF" |
| 64 | + else: |
| 65 | + raise ValueError("Unknown Finite Value") |
| 66 | + |
| 67 | + if isnan: |
| 68 | + payload = bits & 9007199254740991 |
| 69 | + if payload > 0: |
| 70 | + result += '(' + str(payload) + ')' |
| 71 | + |
| 72 | + else: |
| 73 | + # See decimal64_t::to_components() |
| 74 | + if bits & 6917529027641081856 == 6917529027641081856: |
| 75 | + implied_bit = 9007199254740992 |
| 76 | + significand = implied_bit | (bits & 2251799813685247) |
| 77 | + exp = (bits & 2303591209400008704) >> 51 |
| 78 | + else: |
| 79 | + significand = bits & 9007199254740991 |
| 80 | + exp = (bits & 9214364837600034816) >> 53 |
| 81 | + |
| 82 | + exp -= 398 # Bias Value |
| 83 | + |
| 84 | + result = generate_string(significand, exp, sign) |
| 85 | + |
| 86 | + return result |
| 87 | + |
| 88 | +def decode_decimal128(bits): |
| 89 | + |
| 90 | + bits_high = bits >> 64 |
| 91 | + d128_not_11_significand_mask = (562949953421311 << 64) | 18446744073709551615 |
| 92 | + d128_11_significand_mask = (140737488355327 << 64) | 18446744073709551615 |
| 93 | + |
| 94 | + sign = bits_high & 9223372036854775808 != 0 |
| 95 | + isnan = False |
| 96 | + |
| 97 | + if bits_high & 8646911284551352320 == 8646911284551352320: |
| 98 | + |
| 99 | + if bits_high & 9079256848778919936 == 9079256848778919936: |
| 100 | + result = "-SNAN" if sign else "SNAN" |
| 101 | + isnan = True |
| 102 | + elif bits_high & 8935141660703064064 == 8935141660703064064: |
| 103 | + result = "-SNAN" if sign else "QNAN" |
| 104 | + isnan = True |
| 105 | + elif bits_high & 8935141660703064064 == 8646911284551352320: |
| 106 | + result = "-INF" if sign else "INF" |
| 107 | + else: |
| 108 | + raise ValueError("Unknown Finite Value") |
| 109 | + |
| 110 | + if isnan: |
| 111 | + payload = bits & d128_not_11_significand_mask |
| 112 | + if payload > 0: |
| 113 | + result += '(' + str(payload) + ')' |
| 114 | + |
| 115 | + else: |
| 116 | + # See decimal128_t::to_components() |
| 117 | + if bits_high & 6917529027641081856 == 6917529027641081856: |
| 118 | + implied_bit = 562949953421312 << 64 |
| 119 | + significand = implied_bit | (bits & d128_11_significand_mask) |
| 120 | + exp = (bits_high & 2305702271725338624) >> 47 |
| 121 | + else: |
| 122 | + significand = bits & d128_not_11_significand_mask |
| 123 | + exp = (bits_high & 9222809086901354496) >> 49 |
| 124 | + |
| 125 | + exp -= 6176 # Bias Value |
| 126 | + |
| 127 | + result = generate_string(significand, exp, sign) |
| 128 | + |
| 129 | + return result |
0 commit comments