Read the source and its declared rule
This original quantity format uses comma decimal and optional dot-separated groups of three digits. No sign or spaces are allowed; whole-part leading zeros are forbidden except zero itself. It permits nonnegative finite values up to 1,000,000 and retains source text. parseFloat stops at the comma; the corrected grammar validates the whole representation before converting to a JavaScript Number.
| Record | Input JSON |
|---|---|
| Base input | {"raw":"1.234,5"} |
Compare the actual paths
Removing approved grouping dots and changing the declared decimal comma produces 1234.5. This is not a guess about an unknown locale or a currency conversion.
| Path | Output JSON |
|---|---|
| Misleading path | {"accepted":true,"value":1.234,"source":"1.234,5"} |
| Corrected path | {"accepted":true,"value":1234.5,"source":"1.234,5"} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
if(!corrected)return {accepted:true,value:parseFloat(i.raw),source:i.raw};
if(!/^(?:0|[1-9]\d*|[1-9]\d{0,2}(?:\.\d{3})+)(?:,\d+)?$/.test(i.raw))return {accepted:false,error:'decimal-comma-grammar',source:i.raw};
const value=Number(i.raw.replace(/\./g,'').replace(',','.'));
if(!Number.isFinite(value)||value>1000000)return {accepted:false,error:'outside-supplied-range',source:i.raw};
return {accepted:true,value,source:i.raw};
};
const cases=[{"label":"misleading base","input":{"raw":"1.234,5"},"expected":{"accepted":true,"value":1.234,"source":"1.234,5"},"corrected":false},{"label":"corrected base","input":{"raw":"1.234,5"},"expected":{"accepted":true,"value":1234.5,"source":"1.234,5"},"corrected":true},{"label":"mixed separator conventions","input":{"raw":"1,234.5"},"expected":{"accepted":false,"error":"decimal-comma-grammar","source":"1,234.5"},"corrected":true},{"label":"canonical zero","input":{"raw":"0"},"expected":{"accepted":true,"value":0,"source":"0"},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
Check boundaries before the next load
Mixed 1,234.5 is rejected. Canonical zero remains a real zero quantity.
| Case | Input JSON | Expected output JSON |
|---|---|---|
| Mixed separator conventions | {"raw":"1,234.5"} | {"accepted":false,"error":"decimal-comma-grammar","source":"1,234.5"} |
| Canonical zero quantity | {"raw":"0"} | {"accepted":true,"value":0,"source":"0"} |
What value does 1.234,5 mean under this supplied contract?
Show the worked answer
1234.5. The bad 1.234 is only a consumed prefix; mixed separator conventions must not be guessed.