|
|
5 часов назад | |
|---|---|---|
| .. | ||
| cases | 5 часов назад | |
| README.md | 5 часов назад | |
The suite covers every public function declared in
include/pocketpy/common/dmath.h. It replaces the old mixed Python assertions,
exponential/trigonometric vector headers, generators, and aggregate fingerprints.
The general math compatibility tests in tests/704_math.py and
tests/931_math.py are separate from this determinism suite.
Each function has one file in tests/dmath/cases/, for example sqrt.txt,
atan2.txt, or modf.txt. Each row has a descriptive case name, two exact input
words, frozen finite output words, independently calculated references, and an
accuracy allowance. Nonfinite expectations are the readable tokens nan,
+inf, and -inf; their bit patterns are not compared. Hexadecimal
floating-point inputs appear beside each row.
modf orders its outputs as (fraction, integral); sincos uses (sine, cosine).
Classification results are integer 0/1, not binary64 encodings of 0.0/1.0.
| Category | Function groups | Main coverage |
|---|---|---|
| Classification | isfinite, isinf, isnan, isnormal |
All exponent classes, signs, quiet/signaling NaNs |
| Sign and ordering | fabs, copysign, fmin, fmax |
Finite sign changes, NaN classification, NaNs in either operand, zero ties |
| Rounding and remainder | ceil, floor, trunc, modf, fmod |
Fraction boundaries, word/exponent transitions, huge quotients, both outputs |
| Roots | sqrt, cbrt |
Subnormals, exact roots, exponent classes, software sqrt |
| Exponentials | exp, exp2, exp10, pow |
Reduction/table boundaries, underflow ties, overflow, parity, near-one bases |
| Logarithms | log, log2, log10, log_base |
Normalization, neighbors of one, poles, invalid bases |
| Trigonometry | sin, cos, tan, sincos |
Tiny inputs, argument-reduction boundaries, large finite angles, tangent poles |
| Inverse trigonometry | asin, acos, atan, atan2 |
Domain endpoints, polynomial interval boundaries, quadrants, axes, extreme ratios |
The new design contains 1,250 named cases across 31 functions. Mandatory IEEE endpoints such as signed zero and infinity naturally recur; arbitrary inputs, case organization, random streams, and fingerprints were designed anew.
From the repository root:
cmake -S . -B build -DPK_BUILD_MATH_TESTS=ON -DPK_ENABLE_DETERMINISM=ON
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure
# Select a function, or list every group (Windows executables may be in Release/).
build/test_dmath --list
build/test_dmath atan2
build/test_dmath --cases /absolute/path/to/tests/dmath/cases sqrt
# Python bindings, optionally selecting one function.
./main tests/930_dmath.py
./main tests/930_dmath.py modf
./main tests/932_dmath_consumers.py
# Verify the independent references and complete public-function coverage.
python scripts/dmath/generate.py --check
CTest reports each function separately, plus dmath.sqrt_software. The latter
forces the integer-arithmetic sqrt fallback and checks the same expected bits
as hardware sqrt. Normal test execution uses neither assert in C nor the
host libm as a numerical oracle; Release/NDEBUG builds keep all checks active.
Python tests read the same case files. Byte copies through stdc transport
binary64 values without the integer or decimal parsers. Some ABIs quiet
signaling NaNs in transit; only their classification is asserted.
Python rounding return types and exact integer
arguments are checked separately. The six internal-only functions (exp2,
exp10, sincos, isnormal, fmin, fmax) are tested through the C runner.
Power operators, divmod, complex exponentials, and vector rotations have fresh
integration cases in 932_dmath_consumers.py.
scripts/dmath/oracle.py uses
exact integers/Fractions for bit operations, rounding, remainders, and
integer powers. Other references use Decimal roots/exp/log, Machin's formula
for pi, angle reduction and convergent series. Rounded answers must agree
at both 430 and 570 decimal digits. Exact rational evaluation resolves
binary halfway cases, including exp2(-1075). NaNs have classification
checks; infinities have classification/sign checks. Signed zero and exact
finite operations have bitwise checks. Approximation allowances are listed
in scripts/dmath/cases.py; they are test budgets, not global error proofs.modf/sincos. The initial
baseline was accepted only after GCC, Clang, and MSVC independently passed
the accuracy checks and produced identical results. All observed nonzero
errors in this named corpus were one ULP. Tolerances never weaken this
exact-output check.Classification, sign/order, rounding, and remainder groups run under all four rounding modes. Other computations require nearest-even. Entry checks detect unsupported rounding and FTZ/DAZ environments. No test or kernel repairs the embedding application's floating-point environment.
Edit the named function in scripts/dmath/cases.py, then run the generator.
Existing frozen words are preserved only when the case name and both inputs
match. New cases are marked PENDING; normal tests fail until reviewed. The
generator never invokes dmath or automatically recalibrates expected bits.
test_dmath --probe [function] prints candidate words/fingerprints while still
checking independent references and invariants. It is a diagnostic, not a
passing determinism test; CI always runs without --probe.
Review numerical changes before updating frozen words. Compare independent compiler results, run the accuracy checks and sanitizers, and inspect every changed output. Never regenerate a baseline merely to turn a failure green.
| Area | Result |
|---|---|
isfinite, isinf, isnan, isnormal |
Bit classification; full exponent/sign coverage. No arithmetic on NaNs. |
fabs, copysign |
Finite sign-bit operations retained. MSVC x86 may quiet signaling NaNs through its return ABI; NaN encoding is explicitly outside the determinism contract. No ABI workaround or new normalization. |
fmin, fmax |
Fixed single-NaN handling and operand-order-dependent zero ties. Two NaNs produce NaN. Minimum prefers -0; maximum prefers +0. |
ceil, floor, trunc |
Unsigned masks, no out-of-range float-to-int casts. All finite magnitudes supported. |
modf, fmod |
Remainder algorithms retained. Both modf outputs and full finite exponent ranges are covered; NaN results are checked by classification. |
sqrt |
Hardware implementation retained. Software/hardware results use the same corpus and finite-result fingerprint. |
cbrt, asin, acos, atan, atan2 |
Legacy algorithms retained. Boundary/accuracy tests cover these formerly omitted C groups. |
| OpenLibm exp/log/pow/trig kernels | Reviewed special branches, shift/cast bounds, subnormal paths and reduction dependencies. New cases and full UBSan pass; no approximation coefficients changed. |
| NaN/Inf constants | Replaced overflow-expression construction with bit construction: GCC directed-rounding tests found that the former NaN expression could evaluate to finite zero. This fixes classification, without requiring any particular NaN output bits. |
| Build contract | Format, fast-math and excess-precision checks apply to all kernels. Floating-point options belong to CMake; no compiler-specific FP pragmas or local control macros. |
math.modf binding |
Fixed direct float-storage access for integer/non-numeric arguments; use the existing checked numeric conversion. |
The contract assumes IEEE binary64, nearest-even, gradual underflow, disabled
FP traps, and the configured noncontracting arithmetic. errno, FP exception
flags, and NaN payload propagation by arithmetic functions are outside it.
There is no portable preprocessor test for -ffp-contract; the build must pass
the correct option. CPU FMA availability alone does not mean contraction is on.
The legacy Zig/musl source links do not identify the original upstream revision;
this remains a provenance limitation, not a build-time source dependency. The
OpenLibm source revision is pinned separately in 3rd/openlibm/README.md.
The integer-prefix parser overflow discussed earlier is outside dmath and is
not changed here. The new corpus deliberately transports binary64 words so a
parser failure cannot hide or imitate a math-kernel failure.