NumberIntlHelper.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. // Ideally, internacionalization formats implemented through the ECMAScript standards would follow this:
  2. // https://tc39.es/ecma402/#sec-initializedatetimeformat
  3. // https://tc39.es/ecma402/#sec-canonicalizelocalelist
  4. // Along with the implementations of whatever is subsequenlty called.
  5. // As this is not in place (See TODOS in NumberFormatConstructor and DateTimeFormatConstructor) we can arrange
  6. // values that will match the JS behavior using the host logic. This bypasses the ECMAScript standards but can
  7. // do the job for the most common use cases and cultures meanwhile.
  8. namespace Jint.Native.Number;
  9. internal class NumberIntlHelper
  10. {
  11. // Obtined empirically. For all cultures tested, we get a maximum of 3 decimal digits.
  12. private const int JS_MAX_DECIMAL_DIGIT_COUNT = 3;
  13. /// <summary>
  14. /// Checks the powers of 10 of number to count the number of decimal digits.
  15. /// Returns a clamped JS_MAX_DECIMAL_DIGIT_COUNT count.
  16. /// JavaScript will use the shortest representation that accurately represents the value
  17. /// and clamp the decimal digits to JS_MAX_DECIMAL_DIGIT_COUNT.
  18. /// C# fills the digits with zeros up to the culture's numberFormat.NumberDecimalDigits
  19. /// and does not provide the same max (numberFormat.NumberDecimalDigits != JS_MAX_DECIMAL_DIGIT_COUNT).
  20. /// This function matches the JS behaviour for the decimal digits returned, this is the actual decimal
  21. /// digits for a number (with no zeros fill) clamped to JS_MAX_DECIMAL_DIGIT_COUNT.
  22. /// </summary>
  23. public static int GetDecimalDigitCount(double number)
  24. {
  25. for (int i = 0; i < JS_MAX_DECIMAL_DIGIT_COUNT; i++)
  26. {
  27. var powOf10 = number * System.Math.Pow(10, i);
  28. bool isInteger = powOf10 == ((int) powOf10);
  29. if (isInteger)
  30. {
  31. return i;
  32. }
  33. }
  34. return JS_MAX_DECIMAL_DIGIT_COUNT;
  35. }
  36. }