andyearnshaw / Intl.js

Compatibility implementation of the ECMAScript Internationalization API (ECMA-402) for JavaScript -- UNMAINTAINED
Other
1.7k stars 215 forks source link

number.toLocaleString() appends additional digits into formatted text #324

Open bednarp opened 5 years ago

bednarp commented 5 years ago

We are using Intl for unit testing in node environment. We encountered strange behaviour in our tests just in this particular case.

const opt = {
    minimumFractionDigits: 5,
    minimumSignificantDigits: 6
};
const num = 145678.12345679;
console.log(num.toLocaleString("en-US", opt));

Expected output: "145,678.12345679" Received output: "145,678.12345679087"

we setup intl as follows:


const areIntlLocalesSupported = require("intl-locales-supported");
const localesMyAppSupports = ["ms-MY", "ar-EG", "cs-CZ", "sk-SK", "en-US", "en-IN", "te-IN", "ko-KR", "es-ar", "es-sv", "he-IL", "hi", "lo", "vi", "ks", "kk", "cy", "xh", "zu", "zh-Hans-CN-u-nu-hanidec", "de-DE-u-co-phonebk", "de-DE-u-co-phonebk", "th-TH-u-nu-thai", "ja-JP-u-ca-japanese", "en-GB-u-ca-islamic", "cs-CZ-u-nu-tibt", "cs-CZ-u-nu-mlym", "cs-CZ-u-nu-laoo", "cs-CZ-u-nu-guru", "cs-CZ-u-nu-deva", "cs-CZ-u-nu-arabext", "en-IN-u-nu-tamldec", "en-IN-u-nu-orya", "en-IN-u-nu-khmr", "en-IN-u-nu-bali", "en-IN-u-nu-mlym"];

if (global.Intl) {
  if (!areIntlLocalesSupported(localesMyAppSupports)) {
    const IntlPolyfill = require("intl");
    Intl.NumberFormat = IntlPolyfill.NumberFormat;
    Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;

    Number.prototype.toLocaleString = IntlPolyfill.__localeSensitiveProtos.Number.toLocaleString;
    Date.prototype.toLocaleString = IntlPolyfill.__localeSensitiveProtos.Date.toLocaleString;
  }
} else {
  global.Intl = require("intl");
}
fpagnoux commented 5 years ago

Same issue here, the following simple test doesn't pass:

import IntlPolyfill from 'intl'

Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
Intl.NumberFormat = IntlPolyfill.NumberFormat;

it('formatNumber should not add digits', () => {
    const value = 2.3492
    const formatted = (new Intl.NumberFormat('en', {maximumFractionDigits: 20})).format(value)
    expect(formatted).toEqual('2.3492')
});
    Expected value to equal:
      "2.3492"
    Received:
      "2.34920000000000032768"

This seems to be an issue with this library, as the same code run in the browser's console behaves as expected.