# Same measurement, different input rules: comparing sewing calculation packages

A measurement formula can stay the same while its input rules change. That matters when a sewing worksheet, browser tool or command-line script moves between packages. We compared ten small software cases using published Sewlore interfaces to identify their contract differences, rather than make a blanket claim that they are equivalent.

The versions were [npm’s @sewingselami/sewlore-sewing-math](https://www.npmjs.com/package/@sewingselami/sewlore-sewing-math) 0.1.0, [Packagist’s sewlore/measurement-calculators](https://packagist.org/packages/sewlore/measurement-calculators) 1.0.0 and [crates.io’s sewlore-sewing-math](https://crates.io/crates/sewlore-sewing-math/0.1.0) 0.1.0. The [companion harness](https://github.com/gokimedia/sewlore-sewing-tools/tree/6a54ec08e8d4dc75b672ec64815c71da0160b950/examples/measurement-contract-comparison) retains unchanged published source snapshots and SHA-256 values in `source-lock.json`; `python run.py` reproduces its ten-case comparison. No hosted pipeline is claimed.

There is an important language distinction. The Drupal module uses PHP to render its calculator block and configure an optional reference link, but its arithmetic runs in JavaScript. Our comparison executed that JavaScript, the npm functions and the Rust command-line program. It did not invent or test a separate PHP implementation. Minimal unchanged source snapshots were tied to the published versions and file hashes before execution.

## Unit support and input validation

The straightforward case behaved as expected: converting one inch produced 2.54 centimetres in all three interfaces. Millimetres revealed the first difference. The npm conversion function accepts only centimetres and inches, while the Drupal arithmetic and Rust accept millimetres too. For 25.4mm to inches, the latter two returned one. We marked the npm case unsupported instead of inserting an adapter conversion and implying that the package provided it.

Negative input exposed another contract choice. Converting −1cm to inches returned approximately −0.3937007874 in npm. Drupal and Rust rejected the negative length. Neither outcome proves that one package is generally better. A signed coordinate or mathematical difference can be useful, while a physical length often needs a nonnegative constraint. An integration should choose and document the meaning of its input before calling the function.

One deliberately extreme case tested numerical range rather than sewing practice. Converting the positive binary floating-point value represented by `5e-324` centimetres to inches returned zero in both JavaScript converters. Rust rejected the conversion because it would turn a positive length into zero through underflow. This input is a synthetic software stress case, not a plausible fabric measurement. It illustrates why accepting a finite input does not automatically guarantee a useful converted result.

## Stretch recovery and undefined results

The ordinary stretch example agreed across the implementations. Original 10cm, stretched 14cm and released 10.5cm produced 40% stretch, 5% residual change and 87.5% recovered extension. The first two percentages use original length as their denominator. Recovered extension uses the applied extension, which is 4cm here. When all three readings were 10cm, that last denominator was zero. All three interfaces preserved an undefined recovery value, represented as `null` in their JSON output.

A released reading below the original stayed visible. For 10cm, 15cm and 9.5cm, the results included −5% residual change and approximately 110% recovered extension, with an unusual-reading flag. The values were not clamped into a more comfortable range. Mixed units required more care: Rust normalized 10cm, 140mm and 10.5cm and returned the ordinary 40%, 5% and 87.5% result. The JavaScript stretch APIs require a common unit, so the comparison refused that mixed-unit input rather than treating 10 and 140 as directly comparable lengths.

## Check each print axis and their difference

The print-scale case separated two questions. Against a 100mm target, widths and heights of 99.6mm and 100.4mm are each within a 0.5% threshold. Their difference is 0.8 percentage points, however, so npm and Rust also flagged the X/Y gap as excessive. The Drupal math export has no print-scale operation. A passing per-axis check therefore does not imply that the two directions behave uniformly, and no result here prescribes a printer correction.

## Reproduce the comparison

The run generated 30 outcome records from 26 actual numerical calls; four entries were explicitly unsupported. All expected outcomes matched. The inputs were synthetic, and no physical fabric specimens, printer readings or empirical accuracy study were collected. The [Sewlore measurement methods guide](https://sewlore.com/pages/fabric-measurement-methods-guide) gives the recording assumptions behind these calculations. AI assisted this comparison and explanatory draft; its evidence is execution of the published code with stated limitations.

