Bagaimana cara membulatkan angka float di javascript?


298

Saya perlu putaran misalnya 6.688689untuk 6.7, tapi selalu menunjukkan saya 7.

Metode saya:

Math.round(6.688689);
//or
Math.round(6.688689, 1);
//or 
Math.round(6.688689, 2);

Tetapi hasilnya selalu sama 7... Apa yang saya lakukan salah?


28
(6.688689​).toFixed(1);
Shadow Wizard adalah Ear For You

Lihat ini
raina77ow

kemungkinan duplikat angka bulat dalam JavaScript ke N tempat desimal - silakan gunakan pencarian sebelum Anda mengajukan pertanyaan baru.
Felix Kling


1
@ShadowWizard sudah benar. Namun, .toFixedmengembalikan sebuah string. Pastikan untuk memasukkan hasilnya Number(). Lihat jawaban yang diterima, dan lainnya.
Jordan Arseno

Jawaban:


534
Number((6.688689).toFixed(1)); // 6.7

22
Konversi angka menjadi string dan kemudian kembali lagi? Itu tidak bisa cepat.
csl

tidak baik jika angka Anda memiliki desimal kurang dari yang dibutuhkan. Ia menambahkan beberapa
njzk2

2
seperti yang ditunjukkan oleh benchmark JS, ini lebih lambat dari metode
@fivedigit

13
Number((456.1235).toFixed(3)) -> 456.123, Number((1.235).toFixed(2)) -> 1.24... JavaSript Bodoh ...
NoOne

6
Ini mungkin TIDAK MELAKUKAN apa yang Anda harapkan! Hasilnya bahkan dapat bergantung pada browser, lihat pertanyaan ini: stackoverflow.com/q/566564/2224996
maja

199
var number = 6.688689;
var roundedNumber = Math.round(number * 10) / 10;

13
Ini tidak selalu berhasil. Ambil Math.round(1.005*100)/100contoh dari MDN
tybro0103

7
@ tybro0103 Floating point evil: 1.005 * 100 = 100.49999999999999(setidaknya di mesin JS yang saya coba). Itu sebabnya itu tidak bekerja dan mengapa Anda tidak boleh mengandalkan float menjadi sangat akurat.
sudo

1
Salah. Math.round (1.015 * 100) / 100 mengembalikan 1.01 bukannya 1.02
Marco Marsala

81

Gunakan toFixed()fungsi.

(6.688689).toFixed(); // equal to 7
(6.688689).toFixed(1); // equal to 6.7
(6.688689).toFixed(2); // equal to 6.69

5
Ini mungkin TIDAK MELAKUKAN apa yang Anda harapkan! Hasilnya bahkan dapat bergantung pada browser, lihat pertanyaan ini: stackoverflow.com/q/566564/2224996
maja

9
(6.688689) .toFixed (); sama dengan "7" bukan 7. Sama dengan contoh lainnya.
Vado

35

Pembaruan (2019-10). Berkat kode Reece Daniels di bawah ini sekarang tersedia sebagai satu set fungsi yang dikemas dalam paket npm-paket yang diharapkan (lihat).


Anda dapat menggunakan fungsi pembantu dari contoh MDN . Daripada Anda akan memiliki lebih banyak fleksibilitas:

Math.round10(5.25, 0);  // 5
Math.round10(5.25, -1); // 5.3
Math.round10(5.25, -2); // 5.25
Math.round10(5, 0);     // 5
Math.round10(5, -1);    // 5
Math.round10(5, -2);    // 5

Pembaruan (2019-01-15). Sepertinya dokumen MDN tidak lagi memiliki fungsi pembantu ini. Berikut cadangan dengan contoh:

// Closure
(function() {
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */
  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // If the value is negative...
    if (value < 0) {
      return -decimalAdjust(type, -value, exp);
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

Contoh penggunaan:

// Round
Math.round10(55.55, -1);   // 55.6
Math.round10(55.549, -1);  // 55.5
Math.round10(55, 1);       // 60
Math.round10(54.9, 1);     // 50
Math.round10(-55.55, -1);  // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1);      // -50
Math.round10(-55.1, 1);    // -60
Math.round10(1.005, -2);   // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2);  // -1.01
// Floor
Math.floor10(55.59, -1);   // 55.5
Math.floor10(59, 1);       // 50
Math.floor10(-55.51, -1);  // -55.6
Math.floor10(-51, 1);      // -60
// Ceil
Math.ceil10(55.51, -1);    // 55.6
Math.ceil10(51, 1);        // 60
Math.ceil10(-55.59, -1);   // -55.5
Math.ceil10(-59, 1);       // -50

2
?? "Math.round10 bukan fungsi"
Peter Krauss

1
Saya menemukan ini sangat berguna sehingga memukulnya dalam paket npm cepat bagi mereka yang ingin menggunakannya tanpa kembung kode tambahan. Dikreditkan @aspanchenko dengan jawaban asli juga: npmjs.com/package/expected-round
Reece Daniels

19
> +(6.688687).toPrecision(2)
6.7

Sebuah Numberobjek dalam JavaScript memiliki metode yang tidak persis apa yang Anda butuhkan. Metode itu adalah Number.toPrecision([precision]).

Sama seperti .toFixed(1)itu mengubah hasil menjadi string, dan perlu dikonversi kembali menjadi angka. Selesai menggunakan +awalan di sini.

patokan sederhana di laptop saya:

number = 25.645234 typeof number
50000000 x number.toFixed(1) = 25.6 typeof string / 17527ms
50000000 x +(number.toFixed(1)) = 25.6 typeof number / 23764ms
50000000 x number.toPrecision(3) = 25.6 typeof string / 10100ms
50000000 x +(number.toPrecision(3)) = 25.6 typeof number / 18492ms
50000000 x Math.round(number*10)/10 = 25.6 typeof number / 58ms
string = 25.645234 typeof string
50000000 x Math.round(string*10)/10 = 25.6 typeof number / 7109ms

Menurut pendapat saya ini adalah jawaban terbaik (terbaik dalam hal praktik terbaik, pendekatan paling mudah).
cezar

1
1e-10.toPrecision(3): "1.00e-10" - ini putaran ke angka yang signifikan .
Vsevolod Golovanov

9

Jika Anda tidak hanya ingin menggunakan toFixed()tetapi juga ceil()dan floor()pada pelampung maka Anda dapat menggunakan fungsi berikut:

function roundUsing(func, number, prec) {
    var tempnumber = number * Math.pow(10, prec);
    tempnumber = func(tempnumber);
    return tempnumber / Math.pow(10, prec);
}

Menghasilkan:

> roundUsing(Math.floor, 0.99999999, 3)
0.999
> roundUsing(Math.ceil, 0.1111111, 3)
0.112

UPD:

Cara lain yang mungkin adalah ini:

Number.prototype.roundUsing = function(func, prec){
    var temp = this * Math.pow(10, prec)
    temp = func(temp);
    return temp / Math.pow(10, prec)
}

Menghasilkan:

> 6.688689.roundUsing(Math.ceil, 1)
6.7
> 6.688689.roundUsing(Math.round, 1)
6.7
> 6.688689.roundUsing(Math.floor, 1)
6.6

bagaimana cara kita memutuskan kapan harus menggunakan langit-langit, lantai atau bundar untuk pembulatan? Sebagai contoh: roundUsing (Math.round, 1.015, 2) roundUsing (Math.ceil, 1.015, 2) memberikan 2 nilai berbeda Bagaimana kita tahu yang mana yang akan digunakan
gaurav5430

7

Fungsi putaran saya yang diperluas:

function round(value, precision) {
  if (Number.isInteger(precision)) {
    var shift = Math.pow(10, precision);
    // Limited preventing decimal issue
    return (Math.round( value * shift + 0.00000000000001 ) / shift);
  } else {
    return Math.round(value);
  }
} 

Contoh Output:

round(123.688689)     // 123
round(123.688689, 0)  // 123
round(123.688689, 1)  // 123.7
round(123.688689, 2)  // 123.69
round(123.688689, -2) // 100
round(1.015, 2) // 1.02

1
ini mirip dengan jawaban @ fivedigit. ronde (1.015, 2) masih memberikan 1.01 bukannya 1.02
gaurav5430

@ gaurav5430, terima kasih atas laporan Anda, saya telah memperbaikinya.
Nick Tsai

6

Lihat di bawah

var original = 28.59;

var result=Math.round(original*10)/10 akan mengembalikan Anda kembali 28.6

Semoga ini yang kamu mau ..


7
"Jika saya punya uang receh untuk setiap kali saya melihat seseorang menggunakan FLOAT untuk menyimpan mata uang, saya akan memiliki $ 999.997634" - Bill Karwin.
emix

2
Salah. Math.round (1.015 * 100) / 100
Marco Marsala

3
float(value,ndec);
function float(num,x){
this.num=num;
this.x=x;
var p=Math.pow(10,this.x);
return (Math.round((this.num).toFixed(this.x)*p))/p;
}

2

Saya pikir fungsi ini dapat membantu.

 function round(value, ndec){
    var n = 10;
    for(var i = 1; i < ndec; i++){
        n *=10;
    }

    if(!ndec || ndec <= 0)
        return Math.round(value);
    else
        return Math.round(value * n) / n;
}


round(2.245, 2) //2.25
round(2.245, 0) //2

mirip dengan beberapa jawaban lain, ini gagal untuk putaran (1.015, 2), yang seharusnya memberi 1,02
gaurav5430

1

Saya pikir fungsi di bawah ini dapat membantu

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

penggunaan: roundOff(600.23458,2);akan kembali600.23


Bisakah Anda menjelaskan apa yang ditambahkan jawaban ini yang belum dicakup oleh jawaban sebelumnya?
stealththeninja

mirip dengan beberapa jawaban lain, ini gagal untuk putaran (1.015, 2), yang seharusnya memberi 1,02
gaurav5430

1

jika Anda berada di bawah konteks node.js, Anda dapat mencoba mathjs

const math = require('mathjs')
math.round(3.1415926, 2) 
// result: 3.14

1

Ada alternatif .toLocaleString () untuk memformat angka, dengan banyak pilihan mengenai lokal, pengelompokan, pembentukan mata uang, notasi. Beberapa contoh:

Bulat ke 1 desimal, kembalikan float:

const n = +6.688689.toLocaleString('fullwide', {maximumFractionDigits:1})
console.log(
  n, typeof n
)

Membulatkan menjadi 2 desimal, memformat sebagai mata uang dengan simbol yang ditentukan, menggunakan pengelompokan koma untuk ribuan:

console.log(
  68766.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'currency', currency:'USD', useGrouping:true})   
)

Format sebagai mata uang lokal :

console.log(
  68766.688689.toLocaleString('fr-FR', {maximumFractionDigits:2, style:'currency', currency:'EUR'})   
)

Bulat ke minimum 3 desimal, paksa angka nol untuk ditampilkan:

console.log(
  6.000000.toLocaleString('fullwide', {minimumFractionDigits:3})
)

Persen gaya untuk rasio. Masukan * 100 dengan tanda%

console.log(
  6.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'percent'})
)


1
+((6.688689 * (1 + Number.EPSILON)).toFixed(1)); // 6.7
+((456.1235 * (1 + Number.EPSILON)).toFixed(3)); // 456.124

1

Saya punya solusi yang sangat baik jika toFixed () tidak berfungsi.

function roundOff(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}

Contoh

roundOff(10.456,2) //output 10.46

0

Jika Anda menggunakan Browserify hari ini, Anda harus mencoba: roundTo lib NPM yang sangat berguna


0

Tweak kecil untuk jawaban ini :

function roundToStep(value, stepParam) {
   var step = stepParam || 1.0;
   var inv = 1.0 / step;
   return Math.round(value * inv) / inv;
}

roundToStep(2.55, 0.1) = 2.6
roundToStep(2.55, 0.01) = 2.55
roundToStep(2, 0.01) = 2

roundToStep (1,015, 0,002) memberi 1,014. adalah bahwa cara yang benar untuk menggunakannya
gaurav5430

@ gaurav5430 tryroundToStep(1.015, 0.001)
Crashalot
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.