Jak mogę usunąć część dziesiętną z numeru JavaScript?

218

Mam wyniki podziału i chcę odrzucić dziesiętną część wynikowej liczby.

W jaki sposób mogę to zrobić?

JacobTheDev
źródło

Odpowiedzi:

384

Możesz użyć ...

... w zależności od tego, jak chciałeś usunąć przecinek dziesiętny.

Math.trunc()nie jest jeszcze obsługiwany na wszystkich platformach (tj. IE), ale w międzyczasie możesz z łatwością skorzystać z funkcji wypełniania .

Innym sposobem obcięcia części ułamkowej przy doskonałym wsparciu platformy jest użycie operatora bitowego (.eg |0). Efektem ubocznym użycia operatora bitowego na liczbie jest to, że będzie traktował swój operand jako 32-bitową liczbę całkowitą ze znakiem, usuwając w ten sposób część ułamkową. Pamiętaj, że spowoduje to także zawieszenie liczb większych niż 32 bity.


Być może mówisz także o niedokładności zaokrąglania dziesiętnego za pomocą arytmetyki zmiennoprzecinkowej.

Wymagana lektura - co każdy informatyk powinien wiedzieć o arytmetyki zmiennoprzecinkowej .

alex
źródło
29
Należy pamiętać, że Math.floor()będzie zwiększyć wartość liczbową, gdy liczba jest ujemna . Tak więc Math.floor(-1.2) -> -2podczas Math.floor(1.2) -> 1. parseInt(-1.2) -> -1( jak wspomniano w @FloydPink ) odrzuci część dziesiętną zgodnie z oczekiwaniami zarówno dla liczb dodatnich, jak i ujemnych .
Paul T. Rawkeen,
1
@ PaulT.Rawkeen Możesz również użyć operatora bitowego, aby upuścić część dziesiętną, ale pamiętaj, że również obcina się do 32 bitów.
alex
2
z poniższego wynika, że ​​ta odpowiedź jest niestabilna:> (2.305*100)|0 > 230 > (2.3*100)|0 > 229
Jake
4
@Jake Wynik 2.3*100w javascript jest 229.99999999999997, więc wydaje się, że operator bitowy poprawnie wykonuje swoją pracę w twoim przykładzie.
Chad von Nau,
Czy istnieje podobne rozwiązanie, |0które wykorzystuje 64-bitowe liczby całkowite?
Clint,
49

Możesz także użyć operatorów bitowych, aby obciąć przecinek dziesiętny.

na przykład

var x = 9 / 2;
console.log(x); // 4.5

x = ~~x;
console.log(x); // 4

x = -3.7
console.log(~~x) // -3
console.log(x | 0) // -3
console.log(x << 0) // -3

Operacje bitowe są znacznie wydajniejsze niż funkcje matematyczne. Podwójna operator nie bitowe wydaje się również nieznacznie przewyższają x | 0i x << 0bitowe operacje przez znikomą ilość.

// 952 milliseconds
for (var i = 0; i < 1000000; i++) {
    (i * 0.5) | 0;
}

// 1150 milliseconds
for (var i = 0; i < 1000000; i++) {
    (i * 0.5) << 0;
}

// 1284 milliseconds
for (var i = 0; i < 1000000; i++) {
    Math.trunc(i * 0.5);
}

// 939 milliseconds
for (var i = 0; i < 1000000; i++) {
    ~~(i * 0.5);
}

Warto również zauważyć, że operator bitowy nie ma pierwszeństwa przed operacjami arytmetycznymi, więc może być konieczne otoczenie obliczeń nawiasami, aby uzyskać zamierzony wynik:

x = -3.7

console.log(~~x * 2) // -6
console.log(x * 2 | 0) // -7
console.log(x * 2 << 0) // -7

console.log(~~(x * 2)) // -7
console.log(x * 2 | 0) // -7
console.log(x * 2 << 0) // -7

Więcej informacji na temat operatora Double Bitwise Not można znaleźć w Double Bitwise NOT (~~)

Braden Steffaniak
źródło
2
Może być minimalnie wydajny. Proponuję jednak funkcje matematyczne, ponieważ są bardziej czytelne.
ashipj
Możliwe, że to nie zadziała, jeśli liczba całkowita nie będzie reprezentowana jako liczba całkowita 32-bitowa ( stackoverflow.com/a/7488075/3655192 )
Hiroki
30

Ty też możesz to zrobić

parseInt(a/b)
Hari Pachuveetil
źródło
17
Zauważ, że parseIntnie będzie działać niezawodnie dla dużych liczb, ponieważ działa najpierw poprzez konwersję argumentu na ciąg, a dla dużych liczb wynik użyje notacji wykładniczej. Na przykład: var n = 22222222222222222222222; parseInt(n);zwróci 2, ponieważ n.toString()zwraca 2.2222222222222223e+22.
2
Nie używa również parseInt()ze względu na swój cel, którym jest pobranie liczby w ciągu i zwrócenie a Number.
alex
22

Możesz także wyświetlić określoną liczbę cyfr po przecinku (tutaj 2 cyfry), używając następującego kodu:

var num = (15.46974).toFixed(2)
console.log(num) // 15.47
console.log(typeof num) // string

Mahdi Ghafoorian
źródło
4
Pamiętaj, że toFixed () zwraca String, a nie Number. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Jeanmichel Cote
1
Jak to jest odpowiedź, ponieważ OP prosi o usunięcie części dziesiętnej
Isaac
3
Mimo że zwraca ciąg znaków, możesz po prostu użyć metody Number (), aby to poprawić. Number ((15.46974) .toFixed (2))
iPzard
13

Użyj Math.round()funkcji.

Math.round(65.98) // will return 66 
Math.round(65.28) // will return 65
Navdeep Singh
źródło
17
Dla kompletności jest to zwykły JavaScript, a nie zapytanie.
Dave Newton
1
$.round = Math.round;)
alex
12

Zastosowanie Math.round().

(Odpowiedź Alexa jest lepsza; założyłem :)

Dave Newton
źródło
6

W ES2015 dostępna jest funkcja Math.trunc () .

Math.trunc(2.3)                       // 2
Math.trunc(-2.3)                      // -2
Math.trunc(22222222222222222222222.3) // 2.2222222222222223e+22
Math.trunc("2.3")                     // 2
Math.trunc("two")                     // NaN
Math.trunc(NaN)                       // NaN

Nie jest obsługiwany w IE11 lub niższej, ale działa w Edge i każdej innej nowoczesnej przeglądarce.

Chad von Nau
źródło
2
Znasz jakieś odmiany, które pozwalają na obcięcie do X miejsc po przecinku? Czy naiwnością byłoby myśleć, że Math.trunc(value * Math.pow(10,x)) / Math.pow(10,x)to zadziała?
jamiebarrow 21.04.16
2
Hej Jamie, wygląda na to, że działałoby to w większości przypadków, ale jest podatne na zmiennoprzecinkowe błędy. np. value = 2.3i x = 2wróci 2.29. Nie mam lepszej sugestii.
Chad von Nau,
To dla mnie brzmi jak odpowiednia odpowiedź. Bez zaokrąglania górnej lub dolnej. Bez problemów z liczbami ujemnymi. Po prostu odrzuć dziesiętny. Zgodnie z pytaniem.
Namiot Enrique Moreno
2

Jeśli nie zależy ci na roudingu, po prostu przekonwertuj liczbę na ciąg znaków, a następnie usuń wszystko po okresie, w tym po okresie. Działa to niezależnie od tego, czy występuje ułamek dziesiętny, czy nie.

const sEpoch = ((+new Date()) / 1000).toString();
const formattedEpoch = sEpoch.split('.')[0];
Helzgate
źródło
1

toFixed zachowuje się jak okrągły.

Dla zachowania podobnego do podłogi użyj%:

var num = 3.834234;
var floored_num = num - (num % 1); // floored_num will be 3
Shahar H.
źródło
2
Dlaczego uważasz, że jest to lepsze niż korzystanie z Math.floor? Twoje rozwiązanie wydaje się niepotrzebnie złożone i powolne. Nie wiem, jak działa Math.floor, ale spodziewam się, że będzie znacznie bardziej zoptymalizowany. Zastanawiam się także, czy Twoje rozwiązanie może cierpieć z powodu błędów zaokrąglania zmiennoprzecinkowego.
Hans Roerdinkholder
1

Oto szczegółowe wyjaśnienie kompresji za pomocą powyższych postów:

1. Math.trunc (): Służy do usuwania cyfr, po których następuje kropka. Przekształca się niejawnie. Ale nie obsługiwane w IE.

Przykład:

Math.trunc (10.5) // 10

Math.trunc (-10.5) // -10

Inny alternatywny sposób: użycie operatora bitowego nie operatora:

Przykład:

x = 5,5

~~ x // 5

2. Math.floor (): Służy do podania możliwej minimalnej wartości całkowitej. Jest obsługiwany we wszystkich przeglądarkach.

Przykład:

Math.floor (10.5) // 10

Math.floor (-10.5) // -11

3. Math.ceil (): Służy do podania najwyższej możliwej wartości całkowitej. Jest obsługiwany we wszystkich przeglądarkach.

Przykład:

Math.ceil (10.5) // 11

Math.ceil (-10.5) // -10

4. Math.round (): Jest zaokrąglany do najbliższej liczby całkowitej. Jest obsługiwany we wszystkich przeglądarkach.

Przykład:

Math.round (10.5) // 11

Math.round (-10.5) // -10

Math.round (10.49) // 10

Math.round (-10.51) // -11

sreepurna
źródło
1

Na przykład:

var x = 9.656;
x.toFixed(0);           // returns 10
x.toFixed(2);           // returns 9.66
x.toFixed(4);           // returns 9.6560
x.toFixed(6);           // returns 9.656000 

lub

parseInt("10");         // returns 10
parseInt("10.33");      // returns 10
parseInt("10 20 30");   // returns 10
parseInt("10 years");   // returns 10
parseInt("years 10");   // returns NaN  
Kelly K. Audrey
źródło
Nie rozumiem, dlaczego ta odpowiedź nie ma żadnych pochwał, działa dla mnie i jest zintegrowana ze standardami
reaguj
0

W przypadku implementacji ES6 użyj czegoś takiego:

const millisToMinutesAndSeconds = (millis) => {
  const minutes = Math.floor(millis / 60000);
  const seconds = ((millis % 60000) / 1000).toFixed(0);
  return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}
Jared
źródło
0

To jest dla tych, którzy chcą uniemożliwić użytkownikom wprowadzanie liczb dziesiętnych

<input id="myInput" onkeyup="doSomething()" type="number" />

<script>
    function doSomething() {

        var intNum = $('#myInput').val();

        if (!Number.isInteger(intNum)) {
            intNum = Math.round(intNum);
        }

        console.log(intNum);
    }
</script>
Masoud Darvishian
źródło
0

Możesz użyć .toFixed (0), aby usunąć pełną część dziesiętną lub podać liczbę w argumentach do, którą chcesz obciąć dziesiętnie.

Uwaga: toFixed przekonwertuje liczbę na ciąg znaków.

Nikhil Kamani
źródło