Ottieni la parte decimale di un numero con JavaScript


248

Ho numeri float come 3.2e 1.6.

Devo separare il numero nella parte intera e decimale. Ad esempio, un valore di 3.2verrebbe diviso in due numeri, ovvero 3e0.2

Ottenere la parte intera è facile:

n = Math.floor(n);

Ma ho problemi a ottenere la parte decimale. Ho provato questo:

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

Ma non sempre funziona correttamente.

Il codice precedente ha il seguente output:

n = 3.1 => remainer = 1.1

Cosa mi manca qui?


1
Si noti che n = Math.floor(n);restituisce solo il risultato desiderato (la parte intera) per i numeri non negativi
tsemer

Uso semplicissimo % 1no% 2
masterxilo

Risposte:


366

Usa 1, no 2.

js> 2.3 % 1
0.2999999999999998

60
In un mondo in cui 0,299999999999999998 è uguale a 0,3 questo può essere accettabile. Per me non è ... Quindi, per risolvere questa sfida mi asterrei dall'utilizzare Math.*o dalle %operazioni.
Marcel Stör,

62
Per evitare i problemi di arrotondamento in virgola mobile rilevati, l'utilizzo toFixedpotrebbe aiutare in alcune situazioni, ad es . (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt,

12
(2.3 % 1).toFixed(4).substring(2)= "3000"se ne hai bisogno senza0.
Simon_Weaver

14
In un mondo in cui il numero 2.3è sorto e non 2o 3, il numero 0.2999999999999998è perfettamente accettabile nonostante quanto offensivo appaia agli occhi umani.
Gershom,

1
@GershomMaes ci sono una varietà di circostanze in cui quel numero non è accettabile.
Adam Leggett,

92
var decimal = n - Math.floor(n)

Anche se questo non funzionerà con meno numeri, quindi potremmo doverlo fare

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)

Se hai già la parte intera, non è necessario richiamare di Math.floor()nuovo - usa solo la parte intera che hai calcolato.
tvanfosson,

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;usa Math.floor () solo una volta. integr = 3; decimal = 0.20000000000000018;
Nurlan,

2
Per lavorare con un numero negativo, scambia semplicemente Math.floorcon Math.trunc.
Igor Silva,

questo stava restituendo un numero non esatto come mi aspettavo di ottenere 0,80 da 100,80, non 0,79999 ... Ho risolto questo aggiungendo decimal.toFixed (2)
Luis Febro

77

Potresti convertire in stringa, giusto?

n = (n + "").split(".");

17
Funziona bene ovunque tranne che nell'Europa continentale dove una virgola è il separatore decimale. Se hai intenzione di utilizzarlo, ricordati di tenerne conto se sei multinazionale e ti rivolgi all'Europa, poiché questa soluzione non farà un grande lavoro per loro.
cdmdotnet,

8
Vengo dall'Europa continentale con un Firefox francese e funziona. Normalmente useremmo la virgola come separatore decimale in Francia. Il motivo è che in JavaScript non è coinvolta alcuna cultura durante la conversione di un numero in stringa, anche se preferirei usarlo n.toString()anziché n + ""perché è più leggibile.
Gabriel Hautclocq,

2
Se la velocità è critica, allora n + ""è davvero meglio (vedi jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq,

@cdmdotnet JS utilizza .come separatore decimale, quindi stai bene ovunque se il tipo di variabile di input è float. Devi affrontare questo problema solo se il tuo input è stringa. Devo anche notare che questa risposta restituisce una stringa in un array. Una soluzione più completa èparseFloat('0.' + (n + '').split('.')[1])
totymedli

posizione @cdmdotnet soluzione indipendente è qui: stackoverflow.com/a/59469716/1742529
user1742529

32

In che modo 0,2999999999999998 è una risposta accettabile? Se fossi il richiedente, vorrei una risposta di .3. Ciò che abbiamo qui è la falsa precisione e i miei esperimenti con floor,%, ecc. Indicano che Javascript è affezionato alla falsa precisione per queste operazioni. Quindi penso che le risposte che stanno usando la conversione in stringa siano sulla buona strada.

Vorrei fare questo:

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

In particolare, stavo usando 100233.1 e volevo la risposta ".1".


6
Sono generalmente d'accordo, ma non puoi fare affidamento su "." la regex come separatore decimale è un carattere i18n .
Marcel Stör,

1
@jomofrodo In realtà, alcuni potrebbero desiderare il valore non arrotondato. Non ricordo l'OP che chiede un valore arrotondato, ma solo dividere i valori.
VVV,

1
@VVV sì, alcuni potrebbero desiderare il valore non arrotondato. Ma solo perché potresti volere precisione con 9 cifre decimali non significa che i tuoi dati di input lo supportino effettivamente. Ecco perché si chiama "falsa precisione". Se il tuo input è 3.1, la massima precisione che la tua risposta può avere è i decimi, cioè .1. Se rispondi .09 implica che hai effettivamente calcolato / misurato fino alla precisione al 100 °, quando in realtà l'input originale era accurato solo alla precisione al 10 °.
Jomofrodo,

1
@ MarcelStör che può essere facilmente gestito: var decPart = (n.toLocaleString ("en")). Split (".") [1];
Jem

1
.toString()non considera i18n. Il separatore decimale sarà sempre . secondo MDN e le specifiche ECMA
Andrewmat

18

Ecco come lo faccio, che penso sia il modo più semplice per farlo:

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

15

Un modo semplice per farlo è:

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

Sfortunatamente, ciò non restituisce il valore esatto. Tuttavia, ciò è facilmente risolvibile:

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

Puoi usarlo se non conosci il numero di cifre decimali:

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


9

Modo indipendente dalla lingua:

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

si noti che è corretto solo per numeri con una lunghezza frattioanal)


3
Puoi spiegare perché pensi che questo sia indipendente dalla lingua? È JavaScript.
hotzst

4
@hotzst, non esiste una funzione specifica per la lingua
Nurlan,

1
Linguaggio indipendente perché è solo pura matematica. Soluzione pratica. Con la lunghezza della frazione desiderata:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel,

6

È possibile utilizzare la parseInt()funzione per ottenere la parte intera che utilizzare quella per estrarre la parte decimale

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

Oppure potresti usare regex come:

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]}`)
       }
   }
}

decimalPart sta arrivando 0.20000000000000018... questo è davvero difficile da fare perché 0.2 < 0.20000000000000018restituisce true .. 3.2 dovrebbe restituire 0.2: P facendo così tante irregolarità e usando la .toFixed(2)stringa di resi: P
Himanshu Bansal

@HimanshuBansal che è un problema JavaScript (è una domanda stackeoverflow a questo). Potresti usare il secondo metodo come ho suggerito.
Sheki,

Beh, ho una piccola e diversa dichiarazione del problema ... Kinda ha usato entrambi i tuoi modi: P per risolverlo .. ^^
Himanshu Bansal

@HimanshuBansal felice che il mio post abbia aiutato a risolvere il tuo problema!
Sheki,

5

Quanto segue funziona indipendentemente dalle impostazioni regionali per il separatore decimale ... a condizione che venga usato un solo carattere per un separatore.

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);

Non è carino, ma è preciso.


Questa è ovviamente una stringa, quindi potresti aver bisogno prima di parseInt () se la vuoi come numero. Non dovresti aver bisogno di parseFloat () ... a meno che non ci sia qualcosa che mi manca qui con i numeri di base 8 non di base 10 ... qualcosa che ricordo vagamente da anni fa
cdmdotnet,

5

Se la precisione è importante e hai bisogno di risultati coerenti, ecco alcune proposizioni che restituiranno la parte decimale di qualsiasi numero come stringa, incluso lo "0" iniziale. Se ne hai bisogno come float, aggiungi semplicemente var f = parseFloat( result )alla fine.

Se la parte decimale è uguale a zero, verrà restituito "0,0". I numeri Null, NaN e non definiti non vengono testati.

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");

Ecco un link jsPerf: https://jsperf.com/decpart-of-number/

Possiamo vedere che la proposta n. 2 è la più veloce.


non usare nessuno di questi. si interromperanno non appena il rendering del numero passa all'ingegneria. inoltre non sono sensibili alle impostazioni locali.
Spongman,

Potresti spiegare "gli switch di rendering dei numeri all'ingegneria"? Inoltre, la localizzazione non è rilevante perché vogliamo solo la parte decimale di un numero, non una stringa localizzata che rappresenta un numero.
Gabriel Hautclocq,

4

È possibile convertirlo in una stringa e utilizzare il replacemetodo per sostituire la parte intera con zero, quindi riconvertire il risultato in un numero:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');

Questa soluzione non funzionerebbe nell'Europa continentale dove la virgola è il separatore decimale ??
preston,

@preston Puoi sostituire il punto nella regex con qualsiasi altro carattere separatore che ti piace (come /^[^,]/), ma dovresti quindi lasciare il risultato come una stringa (rimuovi l' +operatore) per evitare NaNrisultati.
gion_13,

4

A seconda dell'uso che darai in seguito, ma questa semplice soluzione potrebbe anche aiutarti.

Non sto dicendo che sia una buona soluzione, ma per alcuni casi concreti funziona

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

Ma ci vorrà più tempo della soluzione proposta da @Brian M. Hunt

(2.3 % 1).toFixed(4)

1
Funziona bene ovunque tranne che nell'Europa continentale dove una virgola è il separatore decimale. Se hai intenzione di utilizzarlo, ricordati di tenerne conto se sei multinazionale e ti rivolgi all'Europa, poiché questa soluzione non farà un grande lavoro per loro.
cdmdotnet,

1

Ho avuto un caso in cui sapevo che tutti i numeri in questione avrebbero avuto solo un decimale e volevo ottenere la parte decimale come numero intero, quindi ho finito con questo tipo di approccio:

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

Funziona bene anche con numeri interi, restituendo 0 in questi casi.


1

Sto 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]);
}

Ingresso: -556.123444444

Risultato: 123444444


1

Le funzioni matematiche sono più veloci, ma restituisce sempre valori non nativi previsti. Il modo più semplice che ho trovato è

(3.2+'').replace(/^[-\d]+\./, '')

1

Una buona opzione è trasformare il numero in una stringa e quindi dividerlo.

// 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

In una riga di codice

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];

0

Dopo aver esaminato alcuni di questi, ora sto usando ...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);


0

Anche se sono in ritardo per rispondere a questa domanda, ti preghiamo di dare un'occhiata al codice.

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)

0

Il segno decimale in virgola mobile e il formato numerico possono dipendere dal paese ( .,), quindi la soluzione indipendente, che ha conservato la parte in virgola mobile, è:

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

- è una soluzione internazionalizzata, anziché dipendente dalla posizione:

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

Descrizione della soluzione passo dopo passo:

  1. parseFloat() per garantire la crittografia dell'input
  2. Math.abs() per evitare problemi con numeri negativi
  3. n = parseInt(x) per ottenere la parte decimale
  4. x - n per sottrarre parte decimale
  5. Ora abbiamo un numero con parte decimale zero, ma JavaScript potrebbe darci cifre di parte fluttuanti aggiuntive, che non vogliamo
  6. Quindi, limitare le cifre aggiuntive chiamando toFixed()con il conteggio delle cifre nella parte mobile del numero float originale x. Il conteggio viene calcolato come differenza tra la lunghezza del numero originale xe il numero nnella rappresentazione della stringa.

-1

Usa questo:

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.fracfunzione qui ha 3 modalità:

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 (%)

È semplice :)


-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

4
per me non sembra javascript!
Ch'marr

1
Questo non è java script
Amrut il

In JS dovrebbe essere come: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.