NumberIntlHelper.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  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. {
  10. internal class NumberIntlHelper
  11. {
  12. // Obtined empirically. For all cultures tested, we get a maximum of 3 decimal digits.
  13. private const int JS_MAX_DECIMAL_DIGIT_COUNT = 3;
  14. /// <summary>
  15. /// Checks the powers of 10 of number to count the number of decimal digits.
  16. /// Returns a clamped JS_MAX_DECIMAL_DIGIT_COUNT count.
  17. /// JavaScript will use the shortest representation that accurately represents the value
  18. /// and clamp the decimal digits to JS_MAX_DECIMAL_DIGIT_COUNT.
  19. /// C# fills the digits with zeros up to the culture's numberFormat.NumberDecimalDigits
  20. /// and does not provide the same max (numberFormat.NumberDecimalDigits != JS_MAX_DECIMAL_DIGIT_COUNT).
  21. /// This function matches the JS behaviour for the decimal digits returned, this is the actual decimal
  22. /// digits for a number (with no zeros fill) clamped to JS_MAX_DECIMAL_DIGIT_COUNT.
  23. /// </summary>
  24. public static int GetDecimalDigitCount(double number)
  25. {
  26. for (int i = 0; i < JS_MAX_DECIMAL_DIGIT_COUNT; i++)
  27. {
  28. var powOf10 = number * System.Math.Pow(10, i);
  29. bool isInteger = powOf10 == ((int) powOf10);
  30. if (isInteger)
  31. {
  32. return i;
  33. }
  34. }
  35. return JS_MAX_DECIMAL_DIGIT_COUNT;
  36. }
  37. }
  38. }