Zerowidth CleanerAll measured guides

CLAUDE WATERMARK REMOVER · PRACTICAL TEST

Can a cleaned integer lose precision when converted to Number?

Yes. Our cleaned 9007199254740993 is exact with BigInt, but Number rounds it to 9007199254740992. Removing a selected marker does not validate integer precision.

Tested October 9, 2026 · v24.19.0 · 4 measured runs

Open the Claude text cleaner · Full measured data

Code-point comparison for Large marked integer

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.

Before and after observations; full code points and strings are in the JSON download.
Fixture and modeInput string and code pointsOutput and cleaner statusObserved before / after
Large marked integer
direct string / keep / invisible true
"900719925474099​3"
U+0039 U+0030 U+0030 U+0037 U+0031 U+0039 U+0039 U+0032 U+0035 U+0034 U+0037 U+0034 U+0030 U+0039 U+0039 U+200B U+0033
"9007199254740993"
Removed 1 invisible character
{"number":null,"finite":false,"safeInteger":false,"bigint":{"accepted":false,"errorName":"SyntaxError"}}
{"number":9007199254740992,"finite":true,"safeInteger":false,"bigint":{"accepted":true,"value":"9007199254740993"}}
Large plain integer
direct string / keep / invisible true
"9007199254740993"
U+0039 U+0030 U+0030 U+0037 U+0031 U+0039 U+0039 U+0032 U+0035 U+0034 U+0037 U+0034 U+0030 U+0039 U+0039 U+0033
"9007199254740993"
No selected invisible characters found
{"number":9007199254740992,"finite":true,"safeInteger":false,"bigint":{"accepted":true,"value":"9007199254740993"}}
{"number":9007199254740992,"finite":true,"safeInteger":false,"bigint":{"accepted":true,"value":"9007199254740993"}}
Safe boundary
direct string / keep / invisible true
"9007199254740991"
U+0039 U+0030 U+0030 U+0037 U+0031 U+0039 U+0039 U+0032 U+0035 U+0034 U+0037 U+0034 U+0030 U+0039 U+0039 U+0031
"9007199254740991"
No selected invisible characters found
{"number":9007199254740991,"finite":true,"safeInteger":true,"bigint":{"accepted":true,"value":"9007199254740991"}}
{"number":9007199254740991,"finite":true,"safeInteger":true,"bigint":{"accepted":true,"value":"9007199254740991"}}
Decimal fraction
direct string / keep / invisible true
"12.5"
U+0031 U+0032 U+002E U+0035
"12.5"
No selected invisible characters found
{"number":12.5,"finite":true,"safeInteger":false,"bigint":{"accepted":false,"errorName":"SyntaxError"}}
{"number":12.5,"finite":true,"safeInteger":false,"bigint":{"accepted":false,"errorName":"SyntaxError"}}

Acceptance does not establish exactness

The large marked fixture fails both conversions until the cleaner removes U+200B. Afterward BigInt returns the exact digit sequence ending in three, while Number returns a different integer ending in two and reports false for isSafeInteger. The large plain reference already has that disagreement before cleanup. The safe-boundary reference produces matching decimal text and a true safety flag. The fraction remains acceptable as a Number but is rejected by BigInt. We serialize BigInt observations as decimal strings because ordinary JSON serialization cannot directly store a BigInt value, keeping the exact digits in the record.

This extends a different numeric question

Our earlier small-field experiment asks whether Number accepts a marked string or returns NaN. This matrix asks whether an accepted integer remains exact beyond the safe-integer range and compares a separate integer type. It does not measure a database integer, JSON transport, typed array or arithmetic pipeline. BigInt accepts an integer syntax and does not act as a localized amount parser. The homepage changes a string without choosing a numeric representation. ECMAScript specifies both conversion mechanisms; the downloadable run identifies the values actually observed rather than asserting that every accepted number preserves the input digits.

Choose the representation before conversion

For identifiers or exact integer data, retain the source digits and use the representation required by the destination schema. Validate permitted syntax and range before performing arithmetic or storage. Avoid converting through Number first and then constructing BigInt from an already rounded value. Compare a deliberately edited field with the original intended value, and distinguish fractions from integers rather than deleting punctuation to obtain acceptance. The four fixtures demonstrate a precision boundary in local JavaScript; they do not validate a production data model or prescribe a numeric type for every application.

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

Reference and next check

ECMAScript BigInt conversion 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.