Internal Modules
This section of the documentation provides a detailed look at the internal helper modules used by the Sexagesimal class. This is primarily intended for contributors or those interested in the low-level implementation of the library.
arithmetic Module
This module contains the pure functions for performing base-60 arithmetic on normalized SexagesimalParts.
sexagesimal_calculator.arithmetic
pad_parts
pad_parts(
parts_A: Tuple[int, ...],
parts_B: Tuple[int, ...],
pad_left: bool = True,
) -> Tuple[Tuple[int, ...], Tuple[int, ...]]
Pad two sexagesimal-part tuples so they have equal length.
Summary
Return two new tuples obtained by padding the shorter of the two inputs with zero-valued digits so both tuples share the same length. When pad_left is True zeros are added to the left (most-significant side), which is appropriate for integer-part alignment. When pad_left is False zeros are added to the right (least-significant side), which is appropriate for fractional-part alignment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parts_A
|
Tuple[int, ...]
|
First sequence of base-60 digits (most-significant first). |
required |
parts_B
|
Tuple[int, ...]
|
Second sequence of base-60 digits (most-significant first). |
required |
pad_left
|
bool
|
If True pad on the left (MSB side). If False pad on the right (LSB side). Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
Tuple[int, ...]
|
Tuple[Tuple[int, ...], Tuple[int, ...]]: A pair (padded_A, padded_B) where both |
Tuple[int, ...]
|
tuples have equal length and original ordering of digits is preserved. |
Notes
- This function does not mutate the input tuples; it returns new tuples.
- It is used by arithmetic helpers to align integer and fractional parts prior to digit-wise addition, subtraction and comparison.
compare_magnitude
compare_magnitude(
parts_a: SexagesimalParts, parts_b: SexagesimalParts
) -> int
Compare the magnitudes (absolute values) of two sexagesimal parts.
Summary
Determine which of two normalized SexagesimalParts has the greater magnitude by performing the following checks in order: 1. Compare the lengths of the integer-part tuples (more digits => larger magnitude). 2. If lengths are equal, compare integer parts lexicographically. 3. If integer parts are equal, right-pad fractional parts with zeros to equal length and compare them lexicographically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parts_a
|
SexagesimalParts
|
First normalized parts to compare. |
required |
parts_b
|
SexagesimalParts
|
Second normalized parts to compare. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
int |
int
|
1 if |parts_a| > |parts_b| -1 if |parts_a| < |parts_b| 0 if |parts_a| == |parts_b| |
Notes
- Inputs are expected to be normalized (no leading integer zeros or trailing fractional zeros).
- Fractional parts are padded on the right (least-significant side) before comparison.
- This function compares magnitude only; sign handling is the caller's responsibility.
subtract_magnitude
subtract_magnitude(
larger_parts: SexagesimalParts,
smaller_parts: SexagesimalParts,
) -> SexagesimalParts
Subtract the magnitude of two sexagesimal parts (assumes |larger| >= |smaller|).
Summary
Perform a base-60 digit-wise subtraction of smaller_parts from larger_parts.
The algorithm:
- right-pads fractional parts to equal length and subtracts from least-significant
fractional digit to most-significant, propagating borrows as needed;
- left-pads integer parts to equal length and subtracts with any remaining borrow;
- returns a normalized, immutable SexagesimalParts with a non-negative sign
(caller is responsible for assigning the correct sign if needed).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
larger_parts
|
SexagesimalParts
|
Normalized parts representing the minuend; must
have magnitude greater than or equal to |
required |
smaller_parts
|
SexagesimalParts
|
Normalized parts representing the subtrahend. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
A normalized, immutable parts container for the difference.
The returned |
Notes
- Inputs are expected to be normalized (no leading integer zeros or trailing fractional zeros).
- Fractional parts are padded on the right (LSB side); integer parts are padded on the left (MSB side).
- Borrow propagation may affect multiple fractional and integer places.
add_magnitude
add_magnitude(
a_parts: List[int], b_parts: List[int]
) -> List[int]
Add two sequences of base-60 digits and return the summed digit list.
Summary
Perform digit-wise addition of two lists representing contiguous base-60 digits (most-significant first). The shorter input is left-padded with zeros for alignment, addition proceeds from least-significant to most-significant with carry propagation, and any final carry is expanded into additional high-order digits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a_parts
|
List[int]
|
First sequence of base-60 digits (MSB first). |
required |
b_parts
|
List[int]
|
Second sequence of base-60 digits (MSB first). |
required |
Returns:
| Type | Description |
|---|---|
List[int]
|
List[int]: Resulting sequence of base-60 digits (MSB first). The result may be longer than either input if carries produce new high-order digits. |
Notes
- Inputs are treated immutably; this function builds and returns new lists.
- Designed for internal use when adding combined integer+fractional digit arrays.
multiply_parts
multiply_parts(
a_parts: SexagesimalParts, b_parts: SexagesimalParts
) -> SexagesimalParts
Multiply two normalized sexagesimal parts using long multiplication.
Summary
Perform long multiplication treating the concatenated integer+fractional digit sequences of each operand as contiguous base-60 digits (MSB first). - Combine integer and fractional parts into full digit arrays. - Multiply a_full by each digit of b_full (right-to-left), producing intermediate products with appropriate shifts. - Accumulate intermediate products using add_magnitude. - Re-split the accumulated result into integer and fractional parts according to the total fractional place count. - Normalize the result and set the sign to the XOR of the input signs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a_parts
|
SexagesimalParts
|
Normalized parts of multiplicand. |
required |
b_parts
|
SexagesimalParts
|
Normalized parts of multiplier. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
Normalized parts for the product. Fractional length |
SexagesimalParts
|
equals sum of input fractional lengths; returned parts are normalized |
|
SexagesimalParts
|
(no extraneous leading/trailing zeros) and is_negative reflects the |
|
SexagesimalParts
|
XOR of the input signs. |
Notes
- Inputs are expected normalized (no leading integer zeros, no trailing fractional zeros).
- Uses BASE (60) arithmetic and the helper add_magnitude for accumulation.
- Intermediate carries may increase the length of the result; final normalization ensures canonical representation.
add
add(
a_parts: SexagesimalParts, b_parts: SexagesimalParts
) -> SexagesimalParts
Add two normalized sexagesimal parts (magnitude addition in base-60).
Summary
Compute the sum of two normalized SexagesimalParts by aligning their fractional and integer digit sequences, performing digit-wise addition in base BASE (60), and propagating carries from the least-significant fractional place up through integer places. Any final carry that extends the integer part is expanded into additional high-order digits. The returned parts are normalized and immutable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a_parts
|
SexagesimalParts
|
Left addend; expected to be normalized (no extraneous leading integer zeros or trailing fractional zeros, except canonical zero). |
required |
b_parts
|
SexagesimalParts
|
Right addend; same normalization expectation
as |
required |
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
A normalized, immutable parts container representing |
SexagesimalParts
|
the sum. The returned |
|
SexagesimalParts
|
(this function performs magnitude addition; callers should arrange sign |
|
SexagesimalParts
|
semantics before calling). |
Notes
- Fractional parts are padded on the right (LSB side) for alignment.
- Integer parts are padded on the left (MSB side) for alignment.
- Inputs are treated immutably; this function builds and returns new lists.
- This helper implements magnitude addition; sign-aware addition (mixing positives and negatives) is handled by the higher-level API.
subtract
subtract(
a_parts: SexagesimalParts, b_parts: SexagesimalParts
) -> SexagesimalParts
Subtract two normalized sexagesimal parts (compute a_parts - b_parts).
Summary
Perform sign-aware subtraction of two normalized SexagesimalParts. The function compares magnitudes and delegates to subtract_magnitude to compute the absolute-difference. The returned parts carry the appropriate sign: - If |a_parts| >= |b_parts| the result has the same sign as a_parts (usually non-negative). - If |a_parts| < |b_parts| the result is the negation of the magnitude difference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a_parts
|
SexagesimalParts
|
Minuend parts (normalized: no leading integer zeros or trailing fractional zeros). |
required |
b_parts
|
SexagesimalParts
|
Subtrahend parts (same normalization expectation). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
A normalized, immutable parts container representing a_parts - b_parts. The is_negative flag reflects the correct sign of the result; canonical zero is non-negative. |
Notes
- Inputs are expected to be normalized.
- This helper implements subtraction at the parts level; callers handle higher-level sign semantics when necessary. Borrow/propagation is handled by subtract_magnitude.
conversion Module
This module contains the pure functions for converting between sexagesimal representations and other numerical types like Decimal and Rational.
sexagesimal_calculator.conversion
normalize_parts
normalize_parts(
integer_parts: List[int],
fractional_parts: List[int],
is_negative: bool,
) -> SexagesimalParts
Normalize integer and fractional sexagesimal digit lists into a canonical parts container.
Summary
Cleans up the provided integer and fractional digit lists so they represent a canonical, immutable sexagesimal value. This includes: - removing extraneous leading zeros from the integer part, - removing extraneous trailing zeros from the fractional part, - ensuring a canonical representation for zero (integer_part=(0,), fractional_part=(0,)), - preserving the sign except that zero is always non-negative.
Notes
- The function returns a frozen SexagesimalParts dataclass suitable for storage on Sexagesimal instances.
- The implementation operates in-place on the provided lists (it mutates the lists by popping). Callers who need to keep their originals should pass copies.
- The canonical fractional part is always non-empty; if all fractional digits are stripped, it becomes [0].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
integer_parts
|
List[int]
|
List of integer-place base-60 digits (most-significant first). |
required |
fractional_parts
|
List[int]
|
List of fractional-place base-60 digits (most-significant first). |
required |
is_negative
|
bool
|
Sign flag; will be cleared for the canonical zero representation. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
Immutable, normalized parts with fields: - is_negative (bool) - integer_part (Tuple[int, ...]) - fractional_part (Tuple[int, ...]) |
from_decimal_str
from_decimal_str(value_str: str, accuracy: int = 80) -> str
Converts a decimal number string into a sexagesimal string.
This method is designed to be robust and can handle standard decimal notation ("1.5") as well as scientific notation ("1.5e-2").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value_str
|
str
|
The string representation of the decimal number. |
required |
accuracy
|
int
|
The number of fractional places to compute. |
80
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
A string in the canonical "integer;fractional" format, e.g., "01;30". |
to_rational
to_rational(sexagesimal: Sexagesimal) -> Rational
Convert the internal sexagesimal representation to an exact sympy.Rational.
Summary
Build an exact Rational by summing the integer-place digits weighted by BASEk (k = 0,1,2,...) and the fractional-place digits as digit/BASEk (k = 1,2,...). The sign of the result matches the instance sign; zero is returned as a non-negative Rational.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sexagesimal
|
Sexagesimal
|
The Sexagesimal instance to convert. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Rational |
Rational
|
Exact rational value equivalent to this sexagesimal number. |
Notes
- Uses sympy.Rational for exact fractional arithmetic.
- Integer and fractional contributions are accumulated separately.
- The implementation preserves exactness (no floating-point rounding).
rational_to_sexagesimal_parts
rational_to_sexagesimal_parts(
num: Rational, max_frac_places: int = 80
) -> SexagesimalParts
Convert a sympy.Rational to normalized sexagesimal parts.
Summary
Produce a canonical SexagesimalParts representation for the given exact
Rational num. The function extracts the integer portion as base-60
digits and generates up to max_frac_places fractional base-60 digits
by repeatedly multiplying the fractional remainder by BASE. The result
is normalized (no extraneous leading integer zeros or trailing
fractional zeros) and preserves the sign of the input; zero is returned
using the canonical non-negative representation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num
|
Rational
|
Exact rational value to convert. |
required |
max_frac_places
|
int
|
Maximum number of fractional base-60 digits to produce. Conversion stops early if the fractional part terminates. Defaults to 80. |
80
|
Returns:
| Name | Type | Description |
|---|---|---|
SexagesimalParts |
SexagesimalParts
|
Immutable, normalized parts with fields: - is_negative (bool) - integer_part (Tuple[int, ...]) - fractional_part (Tuple[int, ...]) |
Notes
- Uses exact Rational arithmetic; no floating-point rounding is used.
- If the sexagesimal expansion is non-terminating the result is a
truncated expansion of at most
max_frac_placesdigits. - Callers may increase
max_frac_placesto reduce truncation error.
core Module
This module contains the foundational data structures and constants for the library.
sexagesimal_calculator.core
SexagesimalParts
dataclass
An immutable, private container for the normalized components of a sexagesimal number.
Using frozen=True makes instances immutable and hashable. Using slots=True optimizes memory usage and attribute access speed.
utils Module
This module contains public utility functions that use the Sexagesimal class.
sexagesimal_calculator.utils
increment_table
increment_table(
initial: Union[str, int, float],
increment: Union[str, int, float],
rows: int = 10,
mod: int = 0,
) -> List[str]
Generates a table of incrementing sexagesimal values.