Obtener la parte decimal de un número con JavaScript

247

Tengo números flotantes como 3.2y 1.6.

Necesito separar el número en la parte entera y decimal. Por ejemplo, un valor de 3.2se dividiría en dos números, es decir 3y0.2

Obtener la porción entera es fácil:

n = Math.floor(n);

Pero estoy teniendo problemas para obtener la porción decimal. He intentado esto:

remainer = n % 2; //obtem a parte decimal do rating

Pero no siempre funciona correctamente.

El código anterior tiene el siguiente resultado:

n = 3.1 => remainer = 1.1

¿Qué me estoy perdiendo aquí?

Oscar
fuente
1
Tenga en cuenta que n = Math.floor(n);solo devuelve el resultado deseado (la parte entera) para números no negativos
tsemer
Simplfy use % 1not% 2
masterxilo

Respuestas:

367

Uso 1, no 2.

js> 2.3 % 1
0.2999999999999998
Ignacio Vazquez-Abrams
fuente
59
En un mundo donde 0.2999999999999998 es igual a 0.3 esto puede ser aceptable. Para mí no lo es ... Por lo tanto, para resolver este desafío, me abstendría de usar Math.*u %operaciones.
Marcel Stör
62
Para evitar los problemas de redondeo de coma flotante observados, el uso toFixedpodría ayudar en algunas situaciones, por ejemplo, (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt
12
(2.3 % 1).toFixed(4).substring(2)= "3000"si lo necesitas sin el0.
Simon_Weaver
14
En un mundo donde el número 2.3ha surgido, y no 2o 3, el número 0.2999999999999998es perfectamente aceptable a pesar de lo insultante que parece para los ojos humanos.
Gershom
1
@GershomMaes hay una variedad de circunstancias en las que ese número no es aceptable.
Adam Leggett
92
var decimal = n - Math.floor(n)

Aunque esto no funcionará para números negativos, entonces podríamos tener que hacer

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)
greenimpala
fuente
Si ya tiene la parte entera, no es necesario volver a llamar Math.floor(), solo use la parte entera que ha calculado.
tvanfosson
44
var n = 3.2, integr = Math.floor(n), decimal = n - integr;use Math.floor () solo una vez. integr = 3; decimal = 0.20000000000000018;
Nurlan
2
Para trabajar con un número negativo, simplemente intercambie Math.floorcon Math.trunc.
Igor Silva
esto estaba devolviendo un número no exacto como esperaba obtener 0.80 de 100.80, no 0.79999 ... Resolví esto agregando decimal.toFixed (2)
Luis Febro
76

Podrías convertir a cadena, ¿verdad?

n = (n + "").split(".");
sdleihssirhc
fuente
17
Esto funciona bien en todas partes, excepto en Europa continental, donde una coma es el separador decimal. Si planea usar esto, recuerde tenerlo en cuenta si es multinacional y se dirige a Europa, ya que esta solución no hará un gran trabajo para ellos.
cdmdotnet
8
Soy de Europa continental con un Firefox francés y funciona. Normalmente usaríamos la coma como separador decimal en Francia. La razón es que en JavaScript no hay una cultura involucrada al convertir un Número a una cadena, aunque preferiría usar en n.toString()lugar de n + ""porque es más legible.
Gabriel Hautclocq
2
Si la velocidad es crítica, entonces n + ""es mejor (ver jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq
@cdmdotnet JS utiliza .como separador decimal, por lo que está bien en todas partes si el tipo de su variable de entrada es flotante. Solo tiene que lidiar con ese problema si su entrada es una cadena. También tengo que tener en cuenta que esta respuesta devuelve una cadena en una matriz. Una solución más completa esparseFloat('0.' + (n + '').split('.')[1])
totymedli
La solución independiente de ubicación @cdmdotnet está aquí: stackoverflow.com/a/59469716/1742529
user1742529
32

¿Cómo es 0.2999999999999998 una respuesta aceptable? Si fuera el autor de la pregunta, me gustaría una respuesta de .3. Lo que tenemos aquí es precisión falsa, y mis experimentos con floor,%, etc. indican que a Javascript le gusta la precisión falsa para estas operaciones. Así que creo que las respuestas que están usando la conversión a cadena están en el camino correcto.

Yo haría esto:

var decPart = (n+"").split(".")[1];

Específicamente, estaba usando 100233.1 y quería la respuesta ".1".

jomofrodo
fuente
66
Generalmente estoy de acuerdo pero no puedes confiar en '.' la expresión regular como separador decimal es un carácter i18n .
Marcel Stör
1
@jomofrodo En realidad, algunos podrían querer el valor no redondeado. No recuerdo que el OP solicite un valor redondeado, solo valores divididos.
VVV
1
@VVV sí, algunos pueden querer el valor no redondeado. Pero el hecho de que desee una precisión de 9 decimales no significa que sus datos de entrada realmente lo admitan. Por eso se llama "falsa precisión". Si su entrada es 3.1, la mayor precisión que puede tener su respuesta es décimas, es decir, .1. Si responde .09, implica que realmente ha calculado / medido hasta una precisión de centésimas, cuando en realidad la entrada original solo era precisa con una precisión de décimas.
jomofrodo
1
@ MarcelStör que se puede manejar fácilmente: var decPart = (n.toLocaleString ("en")). Split (".") [1];
jem
1
.toString()no considera i18n. El separador decimal siempre estará de . acuerdo con MDN y la especificación ECMA
Andrewmat
18

Así es como lo hago, que creo que es la forma más sencilla de hacerlo:

var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2
Zantafio
fuente
15

Una forma simple de hacerlo es:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals); //Returns 0.20000000000000018

Desafortunadamente, eso no devuelve el valor exacto. Sin embargo, eso se soluciona fácilmente:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals.toFixed(1)); //Returns 0.2

Puede usar esto si no sabe el número de decimales:

var x = 3.2;
var decimals = x - Math.floor(x);

var decimalPlaces = x.toString().split('.')[1].length;
decimals = decimals.toFixed(decimalPlaces);

console.log(decimals); //Returns 0.2

Ethan
fuente
9

Forma independiente del idioma:

var a = 3.2;
var fract = a * 10 % 10 /10; //0.2
var integr = a - fract; //3

tenga en cuenta que solo se corrige para números con una longitud fractioanal)

Nurlan
fuente
3
¿Puedes explicar por qué crees que esto es independiente del lenguaje? Es JavaScript.
hotzst
44
@hotzst, no hay una función específica del idioma
Nurlan
1
Idioma independiente porque es pura matemática. Solución práctica. Con longitud de fracción deseada:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel
6

Puede usar la parseInt()función para obtener la parte entera que usarla para extraer la parte decimal

var myNumber = 3.2;
var integerPart = parseInt(myNumber);
var decimalPart = myNumber - integerPart;

O podría usar expresiones regulares como:

splitFloat = function(n){
   const regex = /(\d*)[.,]{1}(\d*)/;
   var m;

   if ((m = regex.exec(n.toString())) !== null) {
       return {
          integer:parseInt(m[1]),
          decimal:parseFloat(`0.${m[2]}`)
       }
   }
}
Sheki
fuente
decimalPart está llegando 0.20000000000000018... esto realmente se está haciendo difícil porque 0.2 < 0.20000000000000018devuelve verdadero ... 3.2 se supone que devuelve 0.2: P haciendo tantas irregularidades y usando .toFixed(2)retornos string: P
Himanshu Bansal
@HimanshuBansal es un problema de JavaScript (aquí hay una pregunta de desbordamiento de pila ). Podrías usar el segundo método que sugerí.
Sheki
Bueno, tengo un enunciado de problema un poco diferente ... Utilicé ambas formas: P para resolverlo ... ^^
Himanshu Bansal
@HimanshuBansal me alegra que mi publicación haya ayudado a resolver tu problema.
Sheki
5

Lo siguiente funciona independientemente de la configuración regional para el separador decimal ... con la condición de que solo se use un carácter para un separador.

var n = 2015.15;
var integer = Math.floor(n).toString();
var strungNumber = n.toString();
if (integer.length === strungNumber.length)
  return "0";
return strungNumber.substring(integer.length + 1);

No es bonito, pero es exacto.

cdmdotnet
fuente
Eso es, por supuesto, una cadena, por lo que puede necesitar parseInt () primero si lo desea como un número. No debería ser necesario para parseFloat () ... a menos que haya algo que me falta aquí con la base 8 de base no 10 números ... algo que vagamente recuerdo de hace años
cdmdotnet
5

Si la precisión es importante y necesita resultados consistentes, aquí hay algunas propuestas que devolverán la parte decimal de cualquier número como una cadena, incluido el "0" inicial. Si lo necesita como flotador, simplemente agregue var f = parseFloat( result )al final.

Si la parte decimal es igual a cero, se devolverá "0.0". Nulos, NaN y números indefinidos no se prueban.

1. String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = "0." + ( narray.length > 1 ? narray[1] : "0" );

2. String.substring, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = "0." + (nindex > -1 ? nstring.substring(nindex + 1) : "0");

3. Math.floor, Number.toFixed, String.indexOf

var nstring = (n + ""),
    nindex  = nstring.indexOf("."),
    result  = ( nindex > -1 ? (n - Math.floor(n)).toFixed(nstring.length - nindex - 1) : "0.0");

4. Math.floor, Number.toFixed, String.split

var nstring = (n + ""),
    narray  = nstring.split("."),
    result  = (narray.length > 1 ? (n - Math.floor(n)).toFixed(narray[1].length) : "0.0");

Aquí hay un enlace jsPerf: https://jsperf.com/decpart-of-number/

Podemos ver que la proposición # 2 es la más rápida.

Gabriel Hautclocq
fuente
No uses ninguno de estos. se romperán tan pronto como la representación numérica cambie a ingeniería. Tampoco son sensibles a la configuración regional.
Spongman
¿Podría explicar "los cambios de representación numérica a ingeniería"? Además, la localización no es relevante porque solo queremos la porción decimal de un número, no una cadena localizada que represente un número.
Gabriel Hautclocq
4

Puede convertirlo en una cadena y usar el replacemétodo para reemplazar la parte entera por cero, luego convertir el resultado a un número:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');
gion_13
fuente
¿Esta solución no funcionaría en Europa continental donde la coma es el separador decimal?
preston
@preston Puede reemplazar el punto en la expresión regular con cualquier otro carácter separador que desee (como /^[^,]/), pero luego debe dejar el resultado como una cadena (eliminar el +operador) para evitar NaNresultados.
gion_13
4

Dependiendo del uso que le darás después, pero esta solución simple también podría ayudarte.

No digo que sea una buena solución, pero para algunos casos concretos funciona

var a = 10.2
var c = a.toString().split(".")
console.log(c[1] == 2) //True
console.log(c[1] === 2)  //False

Pero llevará más tiempo que la solución propuesta por @Brian M. Hunt

(2.3 % 1).toFixed(4)
David Sánchez
fuente
1
Esto funciona bien en todas partes, excepto en Europa continental, donde una coma es el separador decimal. Si planea usar esto, recuerde tenerlo en cuenta si es multinacional y se dirige a Europa, ya que esta solución no hará un gran trabajo para ellos.
cdmdotnet
1

Tuve un caso en el que sabía que todos los números en cuestión solo tendrían un decimal y quería obtener la porción decimal como un entero, así que terminé usando este tipo de enfoque:

var number = 3.1,
    decimalAsInt = Math.round((number - parseInt(number)) * 10); // returns 1

Esto funciona muy bien también con enteros, devolviendo 0 en esos casos.

peksipatongeis
fuente
1

Estoy usando:

var n = -556.123444444;
var str = n.toString();
var decimalOnly = 0;

if( str.indexOf('.') != -1 ){ //check if has decimal
    var decimalOnly = parseFloat(Math.abs(n).toString().split('.')[1]);
}

Entrada: -556.123444444

Resultado: 123444444

DavidDunham
fuente
1

Las funciones matemáticas son más rápidas, pero siempre devuelve valores no nativos esperados. La forma más fácil que encontré es

(3.2+'').replace(/^[-\d]+\./, '')
Vasilii Suricov
fuente
1

Una buena opción es transformar el número en una cadena y luego dividirlo.

// Decimal number
let number = 3.2;

// Convert it into a string
let string = number.toString();

// Split the dot
let array = string.split('.');

// Get both numbers
// The '+' sign transforms the string into a number again
let firstNumber  = +array[0]; // 3
let secondNumber = +array[1]; // 2

En una línea de código

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];
Erik Martín Jordán
fuente
0

Después de mirar varios de estos, ahora estoy usando ...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);
Patricio
fuente
0
n = Math.floor(x);
remainder = x % 1;
masterxilo
fuente
0

Aunque llego muy tarde para responder esto, por favor eche un vistazo al código.

let floatValue = 3.267848;
let decimalDigits = floatValue.toString().split('.')[1];
let decimalPlaces = decimalDigits.length;
let decimalDivider = Math.pow(10, decimalPlaces);
let fractionValue = decimalDigits/decimalDivider;
let integerValue = floatValue - fractionValue;

console.log("Float value: "+floatValue);
console.log("Integer value: "+integerValue);
console.log("Fraction value: "+fractionValue)
Hifzur Rahman
fuente
0

El formato de número y signo decimal de coma flotante puede depender del país ( .,), por lo que la solución independiente, que conserva la parte de coma flotante, es:

getFloatDecimalPortion = function(x) {
    x = Math.abs(parseFloat(x));
    let n = parseInt(x);
    return Number((x - n).toFixed(Math.abs((""+x).length - (""+n).length - 1)));
}

- es una solución internacionalizada, en lugar de dependiente de la ubicación:

getFloatDecimalPortion = x => parseFloat("0." + ((x + "").split(".")[1]));

Descripción de la solución paso a paso:

  1. parseFloat() para garantizar la corrección de entrada
  2. Math.abs() para evitar problemas con números negativos
  3. n = parseInt(x) para obtener la parte decimal
  4. x - n para restar parte decimal
  5. Ahora tenemos un número con cero partes decimales, pero JavaScript podría darnos dígitos de partes flotantes adicionales, que no queremos
  6. Por lo tanto, limite los dígitos adicionales llamando toFixed()con el recuento de dígitos en la parte flotante del número flotante original x. El recuento se calcula como la diferencia entre la longitud del número original xy el número nen su representación de cadena.
usuario1742529
fuente
-1

Usa este:

function isNatural(n) {
    n = +n
    if (isNaN(n)) return 'NaN';
    return (n >= 0.0) && (Math.floor(n) === n) && n !== Infinity;
  }

Math.frac = function frac(x, m) {
    x = +x
    if (isNaN(x)) return NaN;
    if (isNatural(x) === true) return 0;
    m = +m || 1

      if (isNatural(x) === false && m === 1){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c
        return d;
      }

      if (isNatural(x) === false && m === 2){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = +b
        return c;
      }

      if (isNatural(x) === false && m === 3){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c * 100
        return d;
      }    
  }

La Math.fracfunción aquí tiene 3 modos:

Math.frac(11.635) //0.635
Math.frac(11.635, 1) //0.635 - default mode is 1
Math.frac(11.635, 2) //635
Math.frac(11.635, 3) //63,5 (%)

Es sencillo :)

Mr_DJA
fuente
-9
float a=3.2;
int b=(int)a; // you'll get output b=3 here;
int c=(int)a-b; // you'll get c=.2 value here
usuario2381223
fuente
44
¡eso no me parece javascript!
Ch'marr
1
Este no es un script de Java
Amrut
En JS debería ser como: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v