Dapatkan bagian desimal dari angka dengan JavaScript

247

Saya memiliki nomor float seperti 3.2dan 1.6.

Saya perlu memisahkan angka menjadi bilangan bulat dan desimal. Misalnya, nilai 3.2akan dibagi menjadi dua angka, yaitu 3dan0.2

Mendapatkan bagian integer itu mudah:

n = Math.floor(n);

Tetapi saya kesulitan mendapatkan bagian desimal. Saya sudah mencoba ini:

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

Tapi itu tidak selalu berhasil dengan benar.

Kode sebelumnya memiliki output sebagai berikut:

n = 3.1 => remainer = 1.1

Apa yang saya lewatkan di sini?

Oscar
sumber
1
Perhatikan bahwa n = Math.floor(n);hanya mengembalikan hasil yang Anda inginkan (bagian bilangan bulat) untuk nomor non-negatif
tsemer
Penggunaan simplfy % 1tidak% 2
masterxilo

Jawaban:

367

Gunakan 1, bukan 2.

js> 2.3 % 1
0.2999999999999998
Ignacio Vazquez-Abrams
sumber
59
Di dunia di mana 0,2999999999999998 sama dengan 0,3 ini mungkin dapat diterima. Bagi saya itu bukan ... Oleh karena itu, untuk mengatasi tantangan ini saya tidak akan menggunakan Math.*atau %operasi.
Marcel Stör
62
Untuk menghindari masalah pembulatan floating point yang dicatat, menggunakan toFixedbisa membantu dalam beberapa situasi misalnya (2.3 % 1).toFixed(4)== "0.3000".
Brian M. Hunt
12
(2.3 % 1).toFixed(4).substring(2)= "3000"jika Anda membutuhkannya tanpa0.
Simon_Weaver
14
Di dunia di mana angkanya 2.3telah muncul, dan bukan 2atau 3, angkanya 0.2999999999999998dapat diterima dengan sempurna meskipun tampak menghina di mata manusia.
Gershom
1
@GershomMaes ada berbagai keadaan di mana nomor itu tidak dapat diterima.
Adam Leggett
92
var decimal = n - Math.floor(n)

Meskipun ini tidak akan bekerja untuk angka minus, jadi kita mungkin harus melakukannya

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)
greenimpala
sumber
Jika Anda sudah memiliki bagian integer, tidak perlu menelepon Math.floor()lagi - cukup gunakan bagian integer yang telah Anda hitung.
tvanfosson
4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;gunakan Math.floor () sekali saja. integr = 3; decimal = 0.20000000000000018;
Nurlan
2
Untuk bekerja dengan angka negatif, cukup tukar Math.floordengan Math.trunc.
Igor Silva
ini mengembalikan angka yang tidak persis seperti yang saya harapkan untuk mendapatkan 0,80 dari 100,80, bukan 0,79999 ... Saya menyelesaikan ini dengan menambahkan desimal.toFixed (2)
Luis Febro
76

Anda dapat mengonversi menjadi string, bukan?

n = (n + "").split(".");
sdleihssirhc
sumber
17
Ini berfungsi dengan baik di mana pun kecuali benua Eropa di mana koma, adalah pemisah desimal. Jika Anda berencana untuk menggunakan ini, ingatlah untuk memperhitungkannya jika Anda multi-nasional dan menargetkan Eropa, karena solusi ini tidak akan melakukan pekerjaan yang baik untuk mereka.
cdmdotnet
8
Saya dari benua Eropa dengan Firefox Perancis dan berfungsi. Biasanya kami akan menggunakan koma sebagai pemisah desimal di Prancis. Alasannya adalah bahwa dalam JavaScript tidak ada budaya yang terlibat ketika mengkonversi Nomor ke string, meskipun saya lebih suka menggunakan n.toString()daripada n + ""karena itu lebih mudah dibaca.
Gabriel Hautclocq
2
Jika kecepatan sangat penting maka n + ""memang lebih baik (lihat jsperf.com/number-vs-number-tostring-vs-string-number )
Gabriel Hautclocq
@cdmdotnet JS digunakan .sebagai pemisah desimal sehingga Anda baik-baik saja di mana-mana jika tipe variabel input Anda mengambang. Anda hanya harus berurusan dengan masalah itu jika input Anda adalah string. Saya juga harus mencatat bahwa jawaban ini mengembalikan string dalam array. Solusi yang lebih lengkap adalahparseFloat('0.' + (n + '').split('.')[1])
totymedli
@cdmdotnet solusi independen lokasi ada di sini: stackoverflow.com/a/59469716/1742529
user1742529
32

Bagaimana 0,2999999999999998 jawaban yang dapat diterima? Jika saya penanya, saya ingin jawaban 0,3. Apa yang kami miliki di sini adalah presisi salah, dan percobaan saya dengan lantai,%, dll menunjukkan bahwa Javascript menyukai presisi palsu untuk operasi ini. Jadi saya pikir jawaban yang menggunakan konversi ke string ada di jalur yang benar.

Saya akan melakukan ini:

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

Secara khusus, saya menggunakan 100233.1 dan saya menginginkan jawaban ".1".

Tomofrodo
sumber
6
Saya umumnya setuju tetapi Anda tidak dapat mengandalkan '.' regex sebagai pemisah desimal adalah karakter i18n .
Marcel Stör
1
@jomofrodo Sebenarnya, beberapa mungkin menginginkan nilai yang tidak bulat. Saya tidak ingat OP meminta nilai bulat, hanya membagi nilai.
VVV
1
@VVV ya, beberapa mungkin menginginkan nilai yang tidak bulat. Tetapi hanya karena Anda mungkin menginginkan presisi hingga 9 tempat desimal tidak berarti data input Anda benar-benar mendukungnya. Itulah mengapa ini disebut "presisi salah". Jika input Anda adalah 3.1, jawaban Anda yang paling presisi adalah sepersepuluh, yaitu .1. Jika Anda menjawab .09 itu menyiratkan bahwa Anda telah benar-benar menghitung / mengukur ke presisi ke-100, padahal sebenarnya input asli hanya akurat untuk presisi ke-10.
jomofrodo
1
@ MarcelStör yang dapat dengan mudah ditangani: var decPart = (n.toLocaleString ("en")). Split (".") [1];
jem
1
.toString()tidak mempertimbangkan i18n. Pemisah desimal akan selalu . sesuai dengan MDN dan spesifikasi ECMA
Andrewmat
18

Inilah cara saya melakukannya, yang menurut saya merupakan cara paling mudah untuk melakukannya:

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

Cara sederhana untuk melakukannya adalah:

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

Sayangnya, itu tidak mengembalikan nilai yang tepat. Namun, itu mudah diperbaiki:

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

Anda dapat menggunakan ini jika Anda tidak tahu jumlah tempat desimal:

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
sumber
9

Cara mandiri bahasa:

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

perhatikan bahwa itu hanya mengoreksi angka dengan satu panjang fractioanal)

Nurlan
sumber
3
Bisakah Anda jelaskan mengapa menurut Anda ini independen terhadap bahasa? Ini adalah JavaScript.
hotzst
4
@hotzst, tidak ada fungsi khusus bahasa
Nurlan
1
Bahasa mandiri karena itu hanya matematika murni. Solusi praktis. Dengan panjang fraksi yang diinginkan:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel
6

Anda dapat menggunakan parseInt()fungsi untuk mendapatkan bagian integer daripada menggunakannya untuk mengekstrak bagian desimal

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

Atau Anda bisa menggunakan regex seperti:

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
sumber
decimalPart akan datang 0.20000000000000018... ini benar-benar semakin sulit dilakukan karena 0.2 < 0.20000000000000018mengembalikan true .. 3,2 seharusnya mengembalikan 0,2: P membuat begitu banyak penyimpangan dan menggunakan .toFixed(2)string pengembalian: P
Himanshu Bansal
@ HimanshuBansal itu masalah JavaScript (hier a stackeoverflow pertanyaan untuk itu). Anda bisa menggunakan metode kedua apa yang saya sarankan.
Sheki
Yah saya punya sedikit pernyataan masalah yang sedikit berbeda ... Agak menggunakan kedua cara Anda: P untuk menyelesaikannya .. ^^
Himanshu Bansal
@ HimanshuBansal senang bahwa posting saya membantu menyelesaikan masalah Anda!
Sheki
5

Berikut ini berfungsi terlepas dari pengaturan regional untuk pemisah desimal ... dengan syarat hanya satu karakter yang digunakan untuk pemisah.

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

Tidak cantik, tapi akurat.

cdmdotnet
sumber
Itu tentu saja sebuah string, jadi Anda mungkin perlu mem-parseInt () terlebih dahulu jika Anda menginginkannya sebagai angka. Anda tidak perlu melakukan parseFloat () ... kecuali ada sesuatu yang saya lewatkan di sini dengan basis 8 bukan basis 10 angka ... sesuatu yang samar-samar saya ingat dari tahun lalu
cdmdotnet
5

Jika ketepatan penting dan Anda membutuhkan hasil yang konsisten, berikut adalah beberapa proposisi yang akan mengembalikan bagian desimal dari angka apa pun sebagai string, termasuk yang memimpin "0.". Jika Anda membutuhkannya sebagai pelampung, cukup tambahkan var f = parseFloat( result )pada akhirnya.

Jika bagian desimal sama dengan nol, "0,0" akan dikembalikan. Null, NaN, dan angka yang tidak ditentukan tidak diuji.

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

Berikut ini tautan jsPerf: https://jsperf.com/decpart-of-number/

Kita dapat melihat bahwa proposisi # 2 adalah yang tercepat.

Gabriel Hautclocq
sumber
jangan gunakan ini. mereka akan rusak begitu nomor rendering beralih ke teknik. mereka juga tidak peka terhadap lokal.
Spongman
Bisakah Anda jelaskan "sakelar rendering angka untuk rekayasa"? Selain itu, pelokalan tidak relevan karena kami hanya menginginkan bagian desimal dari angka, bukan string yang dilokalisasi yang mewakili angka.
Gabriel Hautclocq
4

Anda bisa mengonversinya menjadi string dan menggunakan replacemetode ini untuk mengganti bagian integer dengan nol, lalu mengonversi hasilnya kembali ke angka:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');
gion_13
sumber
Apakah solusi ini tidak berfungsi di benua Eropa di mana koma adalah pemisah desimal ??
Preston
@preston Anda dapat mengganti titik di regex dengan karakter pemisah lain yang Anda suka (seperti /^[^,]/), tetapi Anda kemudian harus meninggalkan hasilnya sebagai string (menghapus +operator) untuk menghindari NaNhasil.
gion_13
4

Tergantung penggunaan yang akan Anda berikan setelahnya, tetapi solusi sederhana ini juga bisa membantu Anda.

Saya tidak mengatakan itu solusi yang baik, tetapi untuk beberapa kasus nyata berhasil

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

Tapi itu akan memakan waktu lebih lama dari solusi yang diusulkan oleh @Brian M. Hunt

(2.3 % 1).toFixed(4)
David Sánchez
sumber
1
Ini berfungsi dengan baik di mana pun kecuali benua Eropa di mana koma, adalah pemisah desimal. Jika Anda berencana untuk menggunakan ini, ingatlah untuk memperhitungkannya jika Anda multi-nasional dan menargetkan Eropa, karena solusi ini tidak akan melakukan pekerjaan yang baik untuk mereka.
cdmdotnet
1

Saya memiliki kasus di mana saya tahu semua angka yang dimaksud hanya akan memiliki satu desimal dan ingin mendapatkan bagian desimal sebagai bilangan bulat sehingga saya akhirnya menggunakan pendekatan semacam ini:

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

Ini berfungsi dengan baik juga dengan integer, menghasilkan 0 dalam kasus tersebut.

peksipatongeis
sumber
1

Saya menggunakan:

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

Input: -556.123444444

Hasil: 123444444

David Dunham
sumber
1

Fungsi matematika lebih cepat, tetapi selalu mengembalikan nilai yang tidak diharapkan asli. Cara termudah yang saya temukan adalah

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

Pilihan yang baik adalah mengubah angka menjadi string dan kemudian membaginya.

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

Dalam satu baris kode

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

Setelah melihat beberapa dari ini, saya sekarang menggunakan ...

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

Meskipun saya sangat terlambat untuk menjawab ini, silakan lihat kodenya.

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
sumber
0

Format tanda dan angka desimal titik mengambang dapat bergantung dari negara ( .,), sehingga solusi independen, yang mempertahankan bagian titik mengambang, adalah:

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

- ini adalah solusi internasional, alih-alih bergantung pada lokasi:

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

Penjelasan solusi langkah demi langkah:

  1. parseFloat() untuk menjamin input input
  2. Math.abs() untuk menghindari masalah dengan angka negatif
  3. n = parseInt(x) untuk mendapatkan bagian desimal
  4. x - n untuk mengurangi bagian desimal
  5. Kami sekarang memiliki angka dengan bagian nol desimal, tetapi JavaScript dapat memberi kami digit bagian mengambang tambahan, yang tidak kami inginkan
  6. Jadi, batasi digit tambahan dengan menelepon toFixed()dengan jumlah digit di bagian mengambang dari nomor float asli x. Hitungan dihitung sebagai perbedaan antara panjang angka asli xdan angka ndalam representasi string mereka.
pengguna1742529
sumber
-1

Gunakan yang ini:

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

The Math.fracFungsi sini memiliki 3 mode:

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

Itu mudah :)

Mr_DJA
sumber
-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
pengguna2381223
sumber
4
itu tidak terlihat seperti javascript bagi saya!
Ch'marr
1
Ini bukan skrip java
Amrut
Dalam JS seharusnya seperti: var a = 3.2; var b = parseInt (a, 10); var c = a - b;
Ju-v