Existe una manera confiable en JavaScript para obtener el número de decimales de un número arbitrario?

Es importante tener en cuenta que no estoy buscando una función de redondeo. Estoy buscando una función que devuelva el número de lugares decimales en la representación decimal simplificada de un número arbitrario. Es decir, tenemos lo siguiente:

decimalPlaces(5555.0);     //=> 0
decimalPlaces(5555);       //=> 0
decimalPlaces(555.5);      //=> 1
decimalPlaces(555.50);     //=> 1
decimalPlaces(0.0000005);  //=> 7
decimalPlaces(5e-7);       //=> 7
decimalPlaces(0.00000055); //=> 8
decimalPlaces(5.5e-7);     //=> 8

Mi primer instinto fue usar las representaciones de cadena: dividir en'.', luego en'e-', y haz los cálculos, así (el ejemplo es detallado):

function decimalPlaces(number) {
  var parts = number.toString().split('.', 2),
    integerPart = parts[0],
    decimalPart = parts[1],
    exponentPart;

  if (integerPart.charAt(0) === '-') {
    integerPart = integerPart.substring(1);
  }

  if (decimalPart !== undefined) {
    parts = decimalPart.split('e-', 2);
    decimalPart = parts[0];
  }
  else {
    parts = integerPart.split('e-', 2);
    integerPart = parts[0];
  }
  exponentPart = parts[1];

  if (exponentPart !== undefined) {
    return integerPart.length +
      (decimalPart !== undefined ? decimalPart.length : 0) - 1 +
      parseInt(exponentPart);
  }
  else {
    return decimalPart !== undefined ? decimalPart.length : 0;
  }
}

Para mis ejemplos anteriores, esta función funciona. Sin embargo, no estoy satisfecho hasta que haya probado todos los valores posibles, así que eliminéNumber.MIN_VALUE.

Number.MIN_VALUE;                      //=> 5e-324
decimalPlaces(Number.MIN_VALUE);       //=> 324

Number.MIN_VALUE * 100;                //=> 4.94e-322
decimalPlaces(Number.MIN_VALUE * 100); //=> 324

l principio, esto parecía razonable, pero luego, en una doble toma, me di cuenta de que5e-324 * 10 debiera ser5e-323! Y luego me di cuenta: estoy lidiando con los efectos de la cuantización de números muy pequeños. No solo se cuantifican los números antes del almacenamiento; Además, algunos números almacenados en binario tienen representaciones decimales irrazonablemente largas, por lo que sus representaciones decimales se están truncando. Esto es desafortunado para mí, porque significa que no puedo obtener su precisión decimal verdadera usando sus representaciones de cadena.

Así que vengo a ti, comunidad de StackOverflow. ¿Alguien entre ustedes conoce una manera confiable de obtener la precisión post-decimal real de un número?

El propósito de esta función, si alguien lo pregunta, es usarla en otra función que convierta un flotante en una fracción simplificada (es decir, devuelve el numerador entero relativamente coprimo y el denominador natural distinto de cero). La única pieza que falta en esta función externa es una forma confiable de determinar el número de lugares decimales en el flotador para que pueda multiplicarlo por la potencia apropiada de 10. Con suerte, lo estoy pensando demasiado.

Respuestas a la pregunta(12)

Su respuesta a la pregunta