Holen Sie sich den Dezimalteil einer Zahl mit JavaScript


247

Ich habe Float-Nummern wie 3.2und 1.6.

Ich muss die Zahl in den ganzzahligen und den dezimalen Teil trennen. Zum Beispiel 3.2würde ein Wert von in zwei Zahlen aufgeteilt, dh 3und0.2

Das Erhalten des ganzzahligen Teils ist einfach:

n = Math.floor(n);

Aber ich habe Probleme, den Dezimalteil zu bekommen. Ich habe das versucht:

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

Aber es funktioniert nicht immer richtig.

Der vorherige Code hat die folgende Ausgabe:

n = 3.1 => remainer = 1.1

Was fehlt mir hier?


1
Beachten Sie, dass n = Math.floor(n);nur das gewünschte Ergebnis (der ganzzahlige Teil) für nicht negative Zahlen zurückgegeben wird
Tsemer

Einfache Verwendung % 1nicht% 2
masterxilo

Antworten:


367

Verwenden Sie 1nicht 2.

js> 2.3 % 1
0.2999999999999998

59
In einer Welt, in der 0,2999999999999998 gleich 0,3 ist, kann dies akzeptabel sein. Für mich ist es nicht ... Um diese Herausforderung zu lösen, würde ich auf die Verwendung Math.*oder %Operationen verzichten.
Marcel Stör

62
Um die festgestellten Gleitkomma-Rundungsprobleme zu vermeiden, kann die Verwendung toFixedin einigen Situationen hilfreich sein, z . B. (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt

12
(2.3 % 1).toFixed(4).substring(2)= "3000"wenn Sie es ohne die0.
Simon_Weaver

14
In einer Welt, in der die Zahl 2.3entstanden ist und nicht 2oder 3, ist die Zahl 0.2999999999999998vollkommen akzeptabel, obwohl sie für das menschliche Auge beleidigend aussieht.
Gershom

1
@GershomMaes Es gibt verschiedene Umstände, unter denen diese Anzahl nicht akzeptabel ist.
Adam Leggett

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

Obwohl dies für Minuszahlen nicht funktioniert, müssen wir dies möglicherweise tun

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

Wenn Sie bereits den ganzzahligen Teil haben, müssen Sie nicht Math.floor()erneut aufrufen. Verwenden Sie einfach den von Ihnen berechneten ganzzahligen Teil.
Tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;benutze Math.floor () nur einmal. integr = 3; decimal = 0.20000000000000018;
Nurlan

2
Um mit einer negativen Zahl zu arbeiten, tauschen Sie einfach Math.floormit Math.trunc.
Igor Silva

Dies gab eine nicht exakte Zahl zurück, wie ich erwartet hatte, 0,80 von 100,80 zu erhalten, nicht 0,79999 ... Ich löste dies durch Hinzufügen von decimal.toFixed (2)
Luis Febro

76

Du könntest in einen String konvertieren, oder?

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

17
Dies funktioniert überall gut, außer in Kontinentaleuropa, wo ein Komma das Dezimaltrennzeichen ist. Wenn Sie dies verwenden möchten, denken Sie daran, dies zu berücksichtigen, wenn Sie multinational sind und auf Europa abzielen, da diese Lösung für sie keine großartige Arbeit leistet.
cdmdotnet

8
Ich komme aus Kontinentaleuropa mit einem französischen Firefox und es funktioniert. Normalerweise würden wir in Frankreich das Komma als Dezimaltrennzeichen verwenden. Der Grund dafür ist , dass in JavaScript gibt es keine Kultur beteiligt ist , wenn eine Zahl zu String Umwandlung, obwohl ich lieber mit n.toString()statt , n + ""weil es besser lesbar ist.
Gabriel Hautclocq

2
Wenn die Geschwindigkeit kritisch ist, n + ""ist sie in der Tat besser (siehe jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq

@cdmdotnet JS wird .als Dezimaltrennzeichen verwendet, sodass Sie überall in Ordnung sind, wenn der Typ Ihrer Eingabevariablen float ist. Sie müssen sich nur mit diesem Problem befassen, wenn Ihre Eingabe eine Zeichenfolge ist. Ich muss auch beachten, dass diese Antwort eine Zeichenfolge in einem Array zurückgibt. Eine vollständigere Lösung istparseFloat('0.' + (n + '').split('.')[1])
totymedli

@cdmdotnet standortunabhängige Lösung ist hier: stackoverflow.com/a/59469716/1742529
user1742529

32

Wie ist 0.2999999999999998 eine akzeptable Antwort? Wenn ich der Fragesteller wäre, würde ich eine Antwort von .3 wollen. Was wir hier haben, ist falsche Präzision, und meine Experimente mit Boden,% usw. zeigen, dass Javascript für diese Operationen falsche Präzision mag. Ich denke also, dass die Antworten, die die Konvertierung in einen String verwenden, auf dem richtigen Weg sind.

Ich würde das tun:

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

Insbesondere habe ich 100233.1 verwendet und wollte die Antwort ".1".


6
Ich stimme im Allgemeinen zu, aber Sie können sich nicht auf '.' Der reguläre Ausdruck als Dezimaltrennzeichen ist ein i18n-Zeichen .
Marcel Stör

1
@jomofrodo Eigentlich möchten einige vielleicht den nicht gerundeten Wert. Ich erinnere mich nicht, dass das OP nach einem gerundeten Wert gefragt hat, sondern nur nach geteilten Werten.
VVV

1
@VVV Ja, einige möchten möglicherweise den nicht gerundeten Wert. Nur weil Sie möglicherweise eine Genauigkeit von 9 Dezimalstellen wünschen, bedeutet dies nicht, dass Ihre Eingabedaten dies tatsächlich unterstützen. Deshalb wird es "falsche Präzision" genannt. Wenn Ihre Eingabe 3,1 ist, kann Ihre Antwort höchstens Zehntel, dh 0,1, haben. Wenn Sie mit .09 antworten, bedeutet dies, dass Sie tatsächlich mit einer Genauigkeit von 100stel berechnet / gemessen haben, obwohl die ursprüngliche Eingabe tatsächlich nur mit einer Genauigkeit von 10stel genau war.
Jomofrodo

1
@ MarcelStör, das leicht zu handhaben ist: var decPart = (n.toLocaleString ("en")). Split (".") [1];
Jem

1
.toString()berücksichtigt i18n nicht. Das Dezimaltrennzeichen entspricht immer . dem MDN und der ECMA-Spezifikation
Andrewmat,

18

So mache ich das, was meiner Meinung nach der einfachste Weg ist:

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

15

Eine einfache Möglichkeit ist:

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

Leider gibt das nicht den genauen Wert zurück. Dies lässt sich jedoch leicht beheben:

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

Sie können dies verwenden, wenn Sie die Anzahl der Dezimalstellen nicht kennen:

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

Sprachunabhängiger Weg:

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

Beachten Sie, dass es nur für Zahlen mit einer Bruchlänge korrigiert.


3
Können Sie erklären, warum Sie dies für sprachunabhängig halten? Es ist JavaScript.
Hotzst

4
@hotzst, es gibt keine sprachspezifische Funktion
Nurlan

1
Sprachunabhängig, weil es nur reine Mathematik ist. Praktische Lösung. Mit gewünschter var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
Bruchlänge

6

Sie können die parseInt()Funktion verwenden, um den ganzzahligen Teil abzurufen, als diese, um den dezimalen Teil zu extrahieren

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

Oder Sie könnten Regex verwenden wie:

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 kommt 0.20000000000000018... das wird wirklich schwierig, weil 0.2 < 0.20000000000000018return true ist. 3.2 soll 0.2: P zurückgeben, so viele Unregelmäßigkeiten verursachen und return .toFixed(2)string verwenden: P
Himanshu Bansal

@HimanshuBansal, das ist ein JavaScript-Problem (hier eine Stackeoverflow-Frage dazu). Sie könnten die zweite Methode verwenden, die ich vorgeschlagen habe.
Sheki

Nun, ich habe eine etwas andere Problemstellung ... Ich habe beide Wege benutzt: P, um sie zu lösen. ^^
Himanshu Bansal

@HimanshuBansal froh, dass mein Beitrag zur Lösung Ihres Problems beigetragen hat!
Sheki

5

Das Folgende funktioniert unabhängig von den regionalen Einstellungen für das Dezimaltrennzeichen ... unter der Bedingung, dass nur ein Zeichen für ein Trennzeichen verwendet wird.

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

Es ist nicht schön, aber es ist genau.


Das ist natürlich eine Zeichenfolge, daher müssen Sie möglicherweise zuerst parseInt () verwenden, wenn Sie es als Zahl möchten. Sie sollten ParloF () nicht parsen müssen ... es sei denn, ich vermisse hier etwas mit Basis 8, nicht Basis 10-Zahlen ... etwas, an das ich mich vor Jahren vage erinnere
cdmdotnet

5

Wenn Präzision wichtig ist und Sie konsistente Ergebnisse benötigen, finden Sie hier einige Vorschläge, die den Dezimalteil einer beliebigen Zahl als Zeichenfolge zurückgeben, einschließlich der führenden "0". Wenn Sie es als Schwimmer benötigen, fügen Sie es var f = parseFloat( result )am Ende hinzu.

Wenn der Dezimalteil gleich Null ist, wird "0.0" zurückgegeben. Null-, NaN- und undefinierte Zahlen werden nicht getestet.

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

Hier ist ein jsPerf-Link: https://jsperf.com/decpart-of-number/

Wir können sehen, dass Satz Nr. 2 der schnellste ist.


Verwenden Sie keine davon. Sie werden unterbrochen, sobald die Nummernwiedergabe auf Engineering umgestellt wird. Sie sind auch nicht länderspezifisch.
Spongman

Könnten Sie "Schalter für das Rendern von Zahlen zum Engineering" erklären? Außerdem ist die Lokalisierung nicht relevant, da wir nur den Dezimalteil einer Zahl wollen, keine lokalisierte Zeichenfolge, die eine Zahl darstellt.
Gabriel Hautclocq

4

Sie können es in eine Zeichenfolge konvertieren und die replaceMethode verwenden, um den ganzzahligen Teil durch Null zu ersetzen. Anschließend können Sie das Ergebnis wieder in eine Zahl konvertieren:

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

Würde diese Lösung nicht in Kontinentaleuropa funktionieren, wo Komma das Dezimaltrennzeichen ist?
Preston

@preston Sie können den Punkt in der Regex durch ein beliebiges anderes Trennzeichen ersetzen (z. B. /^[^,]/). Sie sollten das Ergebnis jedoch als Zeichenfolge belassen (entfernen Sie den +Operator), um NaNErgebnisse zu vermeiden .
gion_13

4

Abhängig von der Verwendung, die Sie später geben werden, könnte Ihnen diese einfache Lösung auch helfen.

Ich sage nicht, dass es eine gute Lösung ist, aber für einige konkrete Fälle funktioniert

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

Es wird jedoch länger dauern als die von @Brian M. Hunt vorgeschlagene Lösung

(2.3 % 1).toFixed(4)

1
Dies funktioniert überall gut, außer in Kontinentaleuropa, wo ein Komma das Dezimaltrennzeichen ist. Wenn Sie dies verwenden möchten, denken Sie daran, dies zu berücksichtigen, wenn Sie multinational sind und auf Europa abzielen, da diese Lösung für sie keine großartige Arbeit leistet.
cdmdotnet

1

Ich hatte einen Fall, in dem ich wusste, dass alle fraglichen Zahlen nur eine Dezimalstelle haben würden, und wollte den Dezimalteil als Ganzzahl erhalten, also habe ich diesen Ansatz gewählt:

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

Dies funktioniert auch mit ganzen Zahlen, wobei in diesen Fällen 0 zurückgegeben wird.


1

Ich benutze:

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

Eingabe: -556.123444444

Ergebnis: 123444444


1

Mathematische Funktionen sind schneller, geben jedoch immer keine nativen Erwartungswerte zurück. Der einfachste Weg, den ich gefunden habe, ist

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

1

Eine gute Option ist es, die Zahl in eine Zeichenfolge umzuwandeln und dann zu teilen.

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

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

0

Nachdem ich mir einige davon angesehen habe, benutze ich jetzt ...

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


0

Obwohl ich sehr spät bin, um dies zu beantworten, schauen Sie sich bitte den Code an.

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

Das Gleitkomma-Dezimalzeichen und das Zahlenformat können von country ( .,) abhängig sein. Eine unabhängige Lösung, bei der der Gleitkomma-Teil erhalten bleibt, lautet also:

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 handelt sich um eine internationalisierte Lösung anstelle einer standortabhängigen:

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

Lösungsbeschreibung Schritt für Schritt:

  1. parseFloat() zur Gewährleistung der Eingangskorrektur
  2. Math.abs() zur Vermeidung von Problemen mit negativen Zahlen
  3. n = parseInt(x) für den Dezimalteil
  4. x - n zum Subtrahieren des Dezimalteils
  5. Wir haben jetzt eine Zahl mit einem Dezimalteil von Null, aber JavaScript könnte uns zusätzliche Ziffern für schwebende Teile geben, die wir nicht wollen
  6. Begrenzen Sie also zusätzliche Ziffern, indem Sie toFixed()mit der Anzahl der Ziffern im schwebenden Teil der ursprünglichen Gleitkommazahl aufrufen x. Die Anzahl wird als Differenz zwischen der Länge der ursprünglichen Nummer xund der Nummer nin ihrer Zeichenfolgendarstellung berechnet .

-1

Verwende das hier:

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

Die Math.fracFunktion hat hier 3 Modi:

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 ist einfach :)


-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
das sieht für mich nicht nach Javascript aus!
Ch'marr

1
Dies ist kein Java-Skript
Amrut

In JS sollte es so sein: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.