CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Why does cleaned -1.5 round to -1 with Math.round?
Our Math.round(-1.5) returns -1, while floor returns -2. The -0.5 control rounds to negative zero, recorded separately from its printed 0. Cleanup makes the marked number parseable; it does not choose a rounding rule.
Open the Claude text cleaner · Full measured data
Measured inputs and outputs
These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Marked negative half direct string / keep / invisible true | "-1.5"U+002D U+0031 U+002E U+200B U+0035 | "-1.5"Removed 1 invisible character | {"number":"NaN","round":"NaN","negativeZero":false,"floor":"NaN","trunc":"NaN","ceil":"NaN"}{"number":"-1.5","round":"-1","negativeZero":false,"floor":"-2","trunc":"-1","ceil":"-1"} |
| Negative half direct string / keep / invisible true | "-1.5"U+002D U+0031 U+002E U+0035 | "-1.5"No selected invisible characters found | {"number":"-1.5","round":"-1","negativeZero":false,"floor":"-2","trunc":"-1","ceil":"-1"}{"number":"-1.5","round":"-1","negativeZero":false,"floor":"-2","trunc":"-1","ceil":"-1"} |
| Positive half direct string / keep / invisible true | "1.5"U+0031 U+002E U+0035 | "1.5"No selected invisible characters found | {"number":"1.5","round":"2","negativeZero":false,"floor":"1","trunc":"1","ceil":"2"}{"number":"1.5","round":"2","negativeZero":false,"floor":"1","trunc":"1","ceil":"2"} |
| Small negative half direct string / keep / invisible true | "-0.5"U+002D U+0030 U+002E U+0035 | "-0.5"No selected invisible characters found | {"number":"-0.5","round":"0","negativeZero":true,"floor":"-1","trunc":"0","ceil":"0"}{"number":"-0.5","round":"0","negativeZero":true,"floor":"-1","trunc":"0","ceil":"0"} |
The selected deletion repairs conversion before rounding
The first source interrupts -1.5 with a selected U+200B. Its initial Number conversion is NaN and every rounding diagnostic records the string NaN. After deletion, Number returns -1.5. Math.round returns -1, floor returns -2, trunc returns -1 and ceil returns -1. The unchanged plain negative-half control reproduces these same outputs. Their disagreement is a policy distinction among numeric operations, not evidence that a hidden character remains in the cleaned decimal spelling. The observer stores explicit number diagnostics as strings so JSON does not replace NaN with null.
Positive and small negative halves expose the tie direction
For positive 1.5, round produces 2 while trunc and floor produce 1. For -0.5, the round string is 0, but Object.is with negative zero is true. That separate boolean retains a detail ordinary string formatting would conceal. The paired positive and negative examples show why nearest-half behavior should be checked on both sides of zero. We chose exactly representable halves intentionally; this experiment does not depend on a binary approximation of a decimal such as 1.005. Display formatting and numeric integer rounding are different operations.
Specify the destination rounding requirement
A destination may require ties toward a chosen direction, truncation, flooring or a different business rule. Pick and test that requirement explicitly instead of assuming all integer conversion functions agree. This page does not implement financial arithmetic, decimal quantization or a cross-language rounding library. It also does not test every boundary around zero or very large values. The linked standard and saved Node results establish the behavior of the fixed calls shown here. Earlier toFixed coverage concerns decimal display strings; these results are numeric operations followed by deliberate diagnostic serialization.
Signed zero needs a retained diagnostic
The negativeZero field applies directly to the Math.round result before it is stringified. Its true result is evidence of that intermediate value rather than a claim that the final text contains a minus sign. Our synthetic decimal strings are not measurements of Claude output. No actual accounting record, classifier score or watermark detector is used. Keep conversion success, rounding choice and final serialization as separate observations when a cleaned decimal appears to change meaning. Repeating character deletion cannot select a different rounding contract downstream.
Reproduce this test
Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.
node reproduce.cjsReference and next check
ECMAScript Math.round provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.