Skip to content

Commit 5c23ca5

Browse files
committed
Add printing of decimal64_t
1 parent d9f5231 commit 5c23ca5

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

extra/decimal_printer.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# https://www.boost.org/LICENSE_1_0.txt
44

55
from detail.decode_decimal32 import decode_decimal32
6+
from detail.decode_decimal64 import decode_decimal64
67
import lldb
78

89
def decimal32_summary(valobj, internal_dict):
@@ -19,8 +20,23 @@ def decimal32_summary(valobj, internal_dict):
1920
except Exception as e:
2021
return f"<invalid decimal32_t: {e}>"
2122

23+
def decimal64_summary(valobj, internal_dict):
24+
"""
25+
Custom summary for decimal64_t type
26+
Displays in scientific notation with cohort preservation
27+
"""
28+
29+
try:
30+
val = valobj.GetNonSyntheticValue()
31+
bits = val.GetChildMemberWithName("bits_").GetValueAsUnsigned()
32+
return decode_decimal64(bits)
33+
34+
except Exception as e:
35+
return f"<invalid decimal64_t: {e}>"
36+
2237
def __lldb_init_module(debugger, internal_dict):
2338
decimal32_pattern = r"^(const )?(boost::decimal::decimal32_t|(\w+::)*decimal32_t)( &| \*)?$"
39+
decimal64_pattern = r"^(const )?(boost::decimal::decimal32_t|(\w+::)*decimal32_t)( &| \*)?$"
2440

2541
debugger.HandleCommand(
2642
f'type summary add -x "{decimal32_pattern}" -e -F decimal_printer.decimal32_summary'
@@ -31,6 +47,15 @@ def __lldb_init_module(debugger, internal_dict):
3147

3248
print("decimal32_t printer loaded successfully")
3349

50+
debugger.HandleCommand(
51+
f'type summary add -x "{decimal64_pattern}" -e -F decimal_printer.decimal64_summary'
52+
)
53+
debugger.HandleCommand(
54+
f'type synthetic add -x "{decimal64_pattern}" -l decimal_printer.DecimalSyntheticProvider'
55+
)
56+
57+
print("decimal64_t printer loaded successfully")
58+
3459
class DecimalSyntheticProvider:
3560
def __init__(self, valobj, internal_dict):
3661
self.valobj = valobj

extra/detail/decode_decimal64.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
def decode_decimal64(bits):
6+
sign = bits & 9223372036854775808 != 0
7+
isnan = False
8+
9+
if bits & 8646911284551352320 == 8646911284551352320:
10+
11+
if bits & 9079256848778919936 == 9079256848778919936:
12+
result = "-SNAN" if sign else "SNAN"
13+
isnan = True
14+
elif bits & 8935141660703064064 == 8935141660703064064:
15+
result = "-SNAN" if sign else "QNAN"
16+
isnan = True
17+
elif bits & 8935141660703064064 == 8646911284551352320:
18+
result = "-INF" if sign else "INF"
19+
else:
20+
raise ValueError("Unknown Finite Value")
21+
22+
if isnan:
23+
payload = bits & 9007199254740991
24+
if payload > 0:
25+
result += '(' + str(payload) + ')'
26+
27+
else:
28+
# See decimal64_t::to_components()
29+
if bits & 6917529027641081856 == 6917529027641081856:
30+
implied_bit = 9007199254740992
31+
significand = implied_bit | (bits & 2251799813685247)
32+
exp = (bits & 2303591209400008704) >> 51
33+
else:
34+
significand = bits & 9007199254740991
35+
exp = (bits & 9214364837600034816) >> 53
36+
37+
exp -= 398 # Bias Value
38+
39+
if significand == 0:
40+
result = "0.0e+0"
41+
else:
42+
n_digits = len(str(abs(significand)))
43+
44+
# If there is no fractional component we want to remove the decimal point and zero
45+
if n_digits > 1:
46+
normalized = significand / (10 ** (n_digits - 1))
47+
total_exp = exp + n_digits - 1
48+
else:
49+
normalized = significand
50+
total_exp = exp
51+
result = f"{'-' if sign else ''}{normalized:.{n_digits - 1}f}e{total_exp:+}"
52+
53+
return result

0 commit comments

Comments
 (0)