agent instructions setup
.NET Test / .NET tests (push) Successful in 55s

This commit is contained in:
2026-09-13 19:22:58 +04:00
parent 9c2d08a3d9
commit ec609b26f7
6 changed files with 251 additions and 56 deletions
+2
View File
@@ -67,6 +67,8 @@ dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences # Parentheses preferences
# Keep explicit grouping for readable mathematical expressions, even when redundant.
dotnet_diagnostic.IDE0047.severity = none
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
+1
View File
@@ -7,6 +7,7 @@
review-* review-*
*.worktrees *.worktrees
.hermes
# User-specific files # User-specific files
*.rsuser *.rsuser
+23 -4
View File
@@ -3,10 +3,9 @@ namespace Just.PreciseMath;
/// <summary> /// <summary>
/// Represents higher precision floating point type /// Represents higher precision floating point type
/// </summary> /// </summary>
/// <remarks> public readonly struct DoubleDouble :
/// Constructs new DoubleDouble from given low and high components IEquatable<DoubleDouble>,
/// </remarks> IEqualityOperators<DoubleDouble, DoubleDouble, bool>
public readonly struct DoubleDouble : IEquatable<DoubleDouble>, IEqualityOperators<DoubleDouble, DoubleDouble, bool>
{ {
internal readonly double _high; internal readonly double _high;
internal readonly double _low; internal readonly double _low;
@@ -18,6 +17,14 @@ public readonly struct DoubleDouble : IEquatable<DoubleDouble>, IEqualityOperato
_low = low; _low = low;
} }
/// <summary>
/// Constructs new DoubleDouble from a given double.
/// </summary>
/// <param name="high">Initial high component</param>
public DoubleDouble(double high) : this(high, 0.0)
{
}
#region Static constants #region Static constants
/// <summary> /// <summary>
/// Represents a value that is not a number (NaN). /// Represents a value that is not a number (NaN).
@@ -31,6 +38,18 @@ public readonly struct DoubleDouble : IEquatable<DoubleDouble>, IEqualityOperato
/// Represents a zero value. /// Represents a zero value.
/// </summary> /// </summary>
public static DoubleDouble Zero => new(); public static DoubleDouble Zero => new();
/// <summary>
/// Represents the ratio of the circumference of a circle to its diameter, specified by the constant, π.
/// </summary>
public static DoubleDouble PI => new(3.141592653589793, 1.2246467991473532e-16);
/// <summary>
/// Represents the natural logarithmic base, specified by the constant, e.
/// </summary>
public static DoubleDouble E => new(2.718281828459045, 1.4456468917292502e-16);
/// <summary>
/// Represents the natural logarithm of value 2.
/// </summary>
public static DoubleDouble LN2 => new(0.6931471805599453, 2.3190468138462996e-17);
#endregion #endregion
/// <summary> /// <summary>
@@ -0,0 +1,42 @@
namespace Just.PreciseMath;
internal static class PreciseMathHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static (double Res, double Err) TwoAdd(double a, double b)
{
double r = a + b;
double t = r - a;
return (r, (a - (r - t)) + (b - t));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static (double Res, double Err) TwoQuickAdd(double a, double b)
{
double r = a + b;
return (r, b - (r - a));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static (double Res, double Err) TwoSubstract(double a, double b)
{
double r = a - b;
double t = r - a;
return (r, (a - (r - t)) - (b + t));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static (double Res, double Err) TwoMultiply(double a, double b)
{
double r = a * b;
return (r, Math.FusedMultiplyAdd(a, b, -r));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static (double Res, double Err) TwoSuare(double a)
{
double r = a * a;
return (r, Math.FusedMultiplyAdd(a, a, -r));
}
}
+159
View File
@@ -0,0 +1,159 @@
# Agent guidelines
These rules apply throughout this repository. Keep purpose, status, usage, and
development instructions in `README.md`; keep agent workflow rules here. Neither
file is a session log.
## Scope and repository map
This is a WIP .NET double-double arithmetic library, not arbitrary-precision math.
Do not claim API completeness or accuracy beyond tested contracts.
- `0-source/Just.PreciseMath/`: library implementation and package metadata.
- `1-tests/Just.PreciseMath.Tests/`: xUnit v3 tests, Shouldly assertions, and
Microsoft.Testing.Platform (MTP) with `coverlet.MTP` coverage.
- `2-benchmarks/Just.PreciseMath.Benchmarks/`: source-free BenchmarkDotNet library
scaffold, not yet a runnable benchmark suite.
- Root `Directory.Build.props` holds shared settings. Each numbered directory's
props explicitly imports it; preserve this import chain.
- `review-legacy/`: optional local reference material, excluded by `.gitignore`.
Start with `review-legacy/Review-Revisited-DoubleDouble.md` when present. The code
and proposed fixes contain known defects: reproduce findings against current
code rather than treating them as correctness oracles. Do not compile, copy
wholesale, or force-add these files. If absent, proceed without them; do not
invent their contents or make validation depend on them.
- Use the ignored, repository-local `.hermes/` directory for plans, checklists,
investigation notes, and handoff context. Create or update notes as useful;
keep them concise and revalidate them against current files. Optional
`.hermes/project-context.md` holds setup and review background. Do not store
secrets, force-add this directory, or make builds or tests depend on it.
## Working rules
- Check both staged and unstaged changes before starting. Preserve the user's
work and index; do not stage, commit, push, publish packages, or rewrite history
without an explicit request. Do not read or expose credentials.
- Read definitions, callers, tests, and relevant configuration before editing.
Limit changes to the request; do not implement the roadmap or repair unrelated WIP code.
- Reproduce numerical bugs with a failing regression test before fixing them.
For new behavior, define the contract and test cases before implementation.
Exercise sibling overloads and operand orders that can share the defect.
- Do not weaken analyzers, nullable checks, warnings-as-errors, or assertions to
get a green build. Explain necessary policy changes before making them.
- Keep dependencies minimal. Check existing references, compatibility, and current
stable releases before adding or upgrading packages.
## C# conventions
Follow `.editorconfig`, not incidental style in unfinished code.
- Use file-scoped namespaces, explicit types rather than `var`, and block-bodied
methods. Preserve the configured expression-bodied property/accessor preferences.
- Use `_camelCase` for non-public instance fields, including internal fields;
`s_camelCase` for non-public mutable static fields; PascalCase for constants
and static readonly fields. Do not rename internal fields to remove underscores.
- Preserve parentheses that make mathematical grouping readable. `IDE0047` is
intentionally disabled; do not re-enable it or remove grouping as style cleanup.
- Document public APIs and non-obvious numerical preconditions. Explain algorithms,
error behavior, and range constraints rather than narrating syntax.
- Tests and benchmarks already have internal access through `InternalsVisibleTo`;
do not widen the public API merely to make a helper testable.
## Numerical correctness
- Treat floating-point evaluation order as part of the algorithm. Do not reassociate
expressions, discard residuals, replace fused multiply-add with multiply-plus-add,
or simplify error-free transforms without justification and regression tests.
Mathematically equivalent formulas can round differently.
- State and verify algorithm preconditions, especially magnitude ordering for
quick-sum transforms, normalization assumptions, and overflow/underflow limits.
- The internal two-component `DoubleDouble` constructor currently does not normalize.
Do not assume arbitrary pairs are canonical. Establish the intended normalization,
NaN, infinity, and signed-zero contracts before changing construction, equality,
hashing, ordering, or classification; keep those operations consistent.
- For affected operations, cover cancellation, widely separated magnitudes, zero
and signed zero, subnormals, extreme finite values, infinities, and NaNs. Check
intermediate overflow/underflow even when the final result is representable.
- Derive expected values from independent high-precision references or exact
binary/rational cases, never from the implementation under test. Record the
reference source or reproducible derivation and justify tolerances.
- Do not collapse both components to `double` or `decimal` to validate double-double
accuracy: that can discard precisely the bits being tested. Use component-aware
or higher-precision comparisons, and inspect sign bits when testing signed zero.
- Smoke tests, coverage percentages, and benchmark output are not proof of
numerical correctness.
## Build and verification
Run commands from the repository root. Read SDK and runner selection from
`global.json`; read framework, language, and dependency versions from project and
props files rather than duplicating version pins here.
For documentation-only changes, validate referenced paths and any new or changed
commands, then run `git diff --check`.
Report commands actually run, their outcomes, and anything not verified. Distinguish
pre-existing failures from failures introduced by the change.
### Code or build changes
Use targeted tests while iterating, then run the full sequence:
```sh
dotnet restore Just.PreciseMath.slnx --locked-mode
dotnet build Just.PreciseMath.slnx -c Release --no-restore
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1
dotnet format Just.PreciseMath.slnx --verify-no-changes --no-restore
git diff --check
```
Use verify-only formatting first. Report unrelated existing violations separately
and validate the changed files; do not reformat the repository to hide failures.
### Test or coverage pipeline changes
After the code/build checks, also run:
```sh
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1 --report-xunit-trx --coverlet --coverlet-output-format cobertura --coverlet-include "[Just.PreciseMath]*"
```
Keep MTP-native options and the empty-suite failure. Do not substitute VSTest
collector commands or remove compile assets from `coverlet.MTP`; generated MTP
registration requires them. Inspect actual TRX and Cobertura output, including
failed-test behavior when changing report collection.
### Packaging changes
After the code/build checks, run:
```sh
dotnet pack 0-source/Just.PreciseMath/Just.PreciseMath.csproj -c Release --no-build
```
Inspect package metadata and the included `README.md` and `LICENSE`. Do not publish.
### Dependency changes
For intentional dependency changes, run `dotnet restore --force-evaluate` and review
all affected `packages.lock.json` files before the locked restore above. Include
lock-file updates in the change; never regenerate them to bypass unexpected restore failures.
## CI and benchmarks
- `.gitea/workflows/test-dotnet.yaml` is the CI source of truth. Keep reports
artifact-only: no badges, publication branches, or repository-write publishing jobs.
- Preserve upload-on-failure and both report globs: `1-tests/**/TestResults/**/*.trx`
and `1-tests/**/TestResults/**/*cobertura*.xml`. Cobertura filenames can be timestamped;
`*.cobertura.xml` alone will miss them.
- Cache NuGet packages, not `bin/` or `obj/`; restore remains necessary on a cache hit.
A local restore does not prove CI cache reuse or remote artifact upload succeeded.
- Before upgrading actions, check each action's required Node runtime against both
the Gitea runner and job image. A recent runner can still launch an old Node image;
`ubuntu-latest` is a configured label, not a guarantee of GitHub's environment.
- Do not add an empty benchmark job. When benchmarks are introduced, add an executable
entry point and cases, then smoke-run them in Release with BenchmarkDotNet's Dry job.
Require discovered/executed cases and verify that benchmark failures fail CI.
- Keep smoke validation separate from performance measurement. Do not gate timing
regressions on a shared runner or compare coverage-instrumented measurements.
Use controlled, repeatable baseline/candidate runs before proposing performance gates.
+24 -52
View File
@@ -1,11 +1,12 @@
# Just.PreciseMath # Just.PreciseMath
**WIP — initial library implementation and one smoke test; numerical correctness is not yet validated.** Extended-precision floating-point arithmetic for .NET using double-double
representations: a high/low pair of `double` values. The goal is to retain more
precision than a single `double` while using a fixed-size representation,
rather than arbitrary-precision arithmetic.
A .NET 10 library being developed for extended-precision floating-point arithmetic > **Work in progress.** The public API is incomplete and may change. Numerical
using double-double representations (a high/low pair of `double` values), with > accuracy has not been validated, and the library is not ready for production use.
common mathematical functions. This is fixed extended precision, not arbitrary
precision; accuracy guarantees and the public API are not settled.
## Planned scope ## Planned scope
@@ -13,64 +14,35 @@ precision; accuracy guarantees and the public API are not settled.
- Common functions including `Abs`, `Sqrt`, `Pow`, `Exp`, and `Log`. - Common functions including `Abs`, `Sqrt`, `Pow`, `Exp`, and `Log`.
- Correctness tests against higher-precision references and performance benchmarks. - Correctness tests against higher-precision references and performance benchmarks.
The [consolidated legacy review](review-legacy/Review-Revisited-DoubleDouble.md) These are development goals, not a list of currently supported features.
is the starting point. Priorities are normalization and special-value contracts
(NaN, infinities, signed zero), corrected constants and scalar subtraction,
consistent comparisons, precision-preserving conversions/formatting, and
range-safe arithmetic and transcendental functions, including cancellation and
subnormal cases. The files in `review-legacy/` contain known defects: they are
reference material only, are not compiled, and should not be used in production.
## Layout ## Build and test
- `0-source/Just.PreciseMath/` — library and package metadata. Requires the .NET 10 SDK in the `10.0.1xx` feature band, as selected by `global.json`.
- `1-tests/Just.PreciseMath.Tests/` — xUnit v3, Shouldly, and MTP-native Coverlet. Run from the repository root:
- `2-benchmarks/Just.PreciseMath.Benchmarks/` — BenchmarkDotNet scaffold.
- `review-legacy/` — original implementation and numerical reviews.
## Development
Use the .NET 10 SDK selected by `global.json` (10.0.1xx, latest installed patch).
Shared settings enable nullable analysis, .NET 10 recommended analyzers, build-time
code-style checks, and warnings as errors. `.editorconfig` retains advisory style
preferences alongside explicitly enforced warning/error rules.
```sh ```sh
dotnet restore Just.PreciseMath.slnx dotnet restore Just.PreciseMath.slnx --locked-mode
dotnet build Just.PreciseMath.slnx -c Release --no-restore dotnet build Just.PreciseMath.slnx -c Release --no-restore
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1
dotnet format Just.PreciseMath.slnx --verify-no-changes --no-restore dotnet format Just.PreciseMath.slnx --verify-no-changes --no-restore
``` ```
Commit each project's `packages.lock.json` with dependency changes. CI caches Test results and coverage reports are available in the `test-results` artifact
NuGet packages using those lock files and always runs `dotnet restore --locked-mode`, on CI workflow runs.
including on cache hits. After intentional dependency updates, run
`dotnet restore --force-evaluate` and review the updated lock files before committing.
Gitea's runner cache must be reachable from the job container, with persistent
storage if the runner itself is recreated. No build outputs are cached.
The initial smoke test checks that `DoubleDouble.One` exposes high and low ## Project structure
components of `1.0` and `0.0`. It exercises the test/coverage pipeline, not the
numerical accuracy of the planned library.
CI collects TRX test results and Cobertura coverage for `Just.PreciseMath` only, - `0-source/Just.PreciseMath/`: library implementation.
excluding test dependencies, and requires at least one test. The `test-results` - `1-tests/Just.PreciseMath.Tests/`: unit tests.
artifact contains TRX test results and timestamped Cobertura XML coverage reports, - `2-benchmarks/Just.PreciseMath.Benchmarks/`: reserved for performance benchmarks.
retained for three days.
Open the workflow run in Gitea Actions and download that artifact. Upload is
attempted even when tests fail; no badges or repository-write token are needed.
To generate the same reports locally: ## Contributing
```sh Follow `.editorconfig` and include regression tests with numerical changes.
dotnet test --solution Just.PreciseMath.slnx -c Release --no-build --minimum-expected-tests 1 --report-xunit-trx --coverlet --coverlet-output-format cobertura --coverlet-include "[Just.PreciseMath]*" Explain the algorithm's assumptions, the source of reference values, and any
``` error tolerances. Include updated `packages.lock.json` files with dependency changes.
Reports are written under each test project's `bin/Release/net10.0/TestResults/`. ## License
The benchmark project deliberately builds as a library without source files;
add an entry point and benchmark cases, then change `OutputType` to `Exe` and run
it in Release without a debugger. No performance results exist yet.
Package metadata uses the development version `0.1.0-dev`. Licensed under the Licensed under the [MIT License](LICENSE).
[MIT License](LICENSE), included in the package.
Do not publish this scaffold as a usable numerical library.