Skip to content

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 smaller_parts.

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 is_negative is always False (magnitude subtraction only).

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 a_parts.

required

Returns:

Name Type Description
SexagesimalParts SexagesimalParts

A normalized, immutable parts container representing

SexagesimalParts

the sum. The returned is_negative flag is set to a_parts.is_negative

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_places digits.
  • Callers may increase max_frac_places to 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.