Memformat angka dengan tepat dua desimal dalam JavaScript

571

Saya memiliki baris kode ini yang membulatkan angka saya ke dua tempat desimal. Tetapi saya mendapatkan angka seperti ini: 10.8, 2.4, dll. Ini bukan ide saya tentang dua tempat desimal jadi bagaimana saya dapat meningkatkan yang berikut?

Math.round(price*Math.pow(10,2))/Math.pow(10,2);

Saya ingin angka seperti 10.80, 2.40, dll. Penggunaan jQuery tidak masalah bagi saya.

Abs
sumber
1
Kode Anda persis seperti apa yang saya cari (untuk mengurangi presisi float ke 7 tempat desimal untuk file JSON yang lebih kecil) Melewati Math.pow untuk speed val = Math.round (val * 10000000) / 10000000);
Pawel
Sebagai jawaban saat-diterima memberikan dibilang hasil yang salah untuk berbagai nilai berkat memperparah ketidaktepatan yang melekat di nomor ( 0.565, 0.575, 1.005), dapat saya sarankan melihat lagi jawaban ini , yang membuat mereka benar?
TJ Crowder
Mungkin Anda ingin memasukkan pustaka sprintf untuk JavaScript stackoverflow.com/questions/610406/…
Thilo
Setelah membulatkan dengan benar dengan metode desimal place shifting dan rounding, Anda bisa menggunakan number.toFixed(x)metode ini untuk mengubahnya menjadi string dengan jumlah nol yang diperlukan. Misalnya bulat 1.34dengan 1.3dengan metode cross-browser kemudian tambahkan 1 nol dan konversi ke string dengan 1.3.toFixed(2)(untuk mendapatkan "1.30").
Edward

Jawaban:

999

Untuk memformat angka menggunakan notasi titik tetap, Anda cukup menggunakan metode toFixed :

(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"

Perhatikan bahwa toFixed()mengembalikan string.

PENTING : Perhatikan bahwa toFixed tidak membulatkan 90% dari waktu, itu akan mengembalikan nilai bulat, tetapi untuk banyak kasus, itu tidak berfungsi.

Contohnya:

2.005.toFixed(2) === "2.00"

MEMPERBARUI:

Saat ini, Anda dapat menggunakan Intl.NumberFormatkonstruktor. Itu bagian dari Spesifikasi API Internasionalisasi Script ECMAS (ECMA402). Ini memiliki cukup dukungan yang baik peramban , bahkan termasuk IE11, dan itu didukung sepenuhnya di Node.js .

const formatter = new Intl.NumberFormat('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});

console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"

Anda juga dapat menggunakan toLocaleStringmetode ini, yang secara internal akan menggunakan IntlAPI:

const format = (num, decimals) => num.toLocaleString('en-US', {
   minimumFractionDigits: 2,      
   maximumFractionDigits: 2,
});


console.log(format(2.005)); // "2.01"
console.log(format(1.345)); // "1.35"

API ini juga memberi Anda beragam opsi untuk diformat, seperti ribuan pemisah, simbol mata uang, dll.

CMS
sumber
17
Tidak bekerja secara konsisten di semua browser, yaitu (0.09).toFixed(1);memberi 0,0 di IE8
ajbeaven
41
tetap tidak bulat, Anda dapat melakukannya terlebih dahulu: (Math.round (0,09)). toFixed (1);
rekans
32
@ Kunans: Ini salah. Math.Round(0.09)akan kembali 0sehingga ini akan selalu memberi 0.0...
Chris
28
Ini adalah ide yang buruk di sebagian besar situasi, itu mengubah angka menjadi string atau nomor float point dalam beberapa kasus.
Ash Blue
80
Harus setuju dengan @AshBlue di sini ... ini hanya aman untuk memformat presentasi nilai. Dapat memecahkan kode dengan perhitungan lebih lanjut. Jika tidak Math.round(value*100)/100berfungsi lebih baik untuk 2DP.
UpTheCreek
98

Ini adalah topik lama tetapi hasil Google masih peringkat teratas dan solusi yang ditawarkan berbagi masalah desimal titik mengambang yang sama. Ini adalah fungsi (sangat umum) yang saya gunakan, terima kasih kepada MDN :

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(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));
}

Seperti yang bisa kita lihat, kita tidak mendapatkan masalah ini:

round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27

Kemurahan hati ini juga menyediakan beberapa hal keren:

round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123

Sekarang, untuk menjawab pertanyaan OP, kita harus mengetik:

round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"

Atau, untuk fungsi yang lebih ringkas, kurang generik:

function round2Fixed(value) {
  value = +value;

  if (isNaN(value))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

  // Shift back
  value = value.toString().split('e');
  return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}

Anda dapat menyebutnya dengan:

round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"

Berbagai contoh dan tes (terima kasih kepada @ tj-crowder !):

astorije
sumber
1
Bagaimana tidak ada cara sederhana untuk melakukan ini? ES6 untuk menyelamatkan?
zero_cool
Terima kasih telah memposting polyfill MDN. Pada halaman MDN yang tertaut, polyfill tidak lagi ada. Saya ingin tahu mengapa itu dihapus ...
King Holly
43

Saya biasanya menambahkan ini ke perpustakaan pribadi saya, dan setelah beberapa saran dan menggunakan solusi @TIMINeutron juga, dan membuatnya dapat disesuaikan untuk panjang desimal, yang ini paling cocok:

function precise_round(num, decimals) {
   var t = Math.pow(10, decimals);   
   return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}

akan bekerja untuk pengecualian yang dilaporkan.

Miguel
sumber
2
precision_round (1.275,2) adalah 1.27?
allenhwkim
2
@Imre Ubah nilai kembali ke (Math.round (num * Math.pow (10, desimal)) / Math.pow (10, desimal)). ToFixed (2); dan Anda tidak akan lagi memiliki masalah itu.
dkroy
6
di mana Anda menyatakan "tanda" dan "dec" jika fungsi kedua Anda diambil sebagaimana mestinya tidak memilikinya sebagai tidak terdefinisi?
Ady Ngom
2
Saya telah menambahkan workarround untuk metode tanda missign di IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Armin
1
@Armin Perbaikan Anda juga membuatnya berfungsi di Safari. Fungsi asli tidak berfungsi di Safari.
Dave
19

Saya tidak tahu mengapa saya tidak dapat menambahkan komentar pada jawaban sebelumnya (mungkin saya buta tanpa harapan, tidak tahu), tetapi saya menemukan solusi menggunakan jawaban @ Miguel:

function precise_round(num,decimals) {
   return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}

Dan dua komentarnya (dari @bighostkim dan @Imre):

  • Masalah dengan precise_round(1.275,2) tidak mengembalikan 1.28
  • Masalah dengan precise_round(6,2)tidak mengembalikan 6,00 (seperti yang dia inginkan).

Solusi terakhir saya adalah sebagai berikut:

function precise_round(num,decimals) {
    var sign = num >= 0 ? 1 : -1;
    return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}

Seperti yang Anda lihat saya harus menambahkan sedikit "koreksi" (bukan itu yang sebenarnya, tetapi karena Math.round adalah lossy - Anda dapat memeriksanya di jsfiddle.net - ini adalah satu-satunya cara saya tahu bagaimana "memperbaiki" " Itu). Itu menambahkan 0,001 ke angka yang sudah empuk, jadi itu menambahkan 1tiga 0s di sebelah kanan nilai desimal. Jadi harus aman digunakan.

Setelah itu saya menambahkan .toFixed(decimal)untuk selalu menampilkan angka dalam format yang benar (dengan jumlah desimal yang tepat).

Jadi cukup banyak. Gunakan dengan baik;)

EDIT: menambahkan fungsionalitas ke "koreksi" angka negatif.

tfrascaroli
sumber
2
"Koreksi" sebagian besar aman, tetapi misalnya precise_round(1.27499,2)sekarang juga mengembalikan 1,28 ... Itu tidak Math.roundrugi; cara komputer secara internal menyimpan nilai floating point adalah. Pada dasarnya, Anda pasti gagal dengan beberapa nilai sebelum data bahkan sampai ke fungsi Anda :)
Imre
@Imre, Anda benar sekali. Itu sebabnya saya menjelaskan apa yang dilakukan 0.001 di sana, kalau-kalau ada yang ingin membuatnya "lebih tepat " atau bahkan menghapusnya (jika Anda memiliki komputer super dengan 2 Mbytes per float, yang saya pikir tidak ada orang di sini yang melakukannya ;)
tfrascaroli
1
Sebenarnya, spesifikasi bahasa cukup spesifik tentang menggunakan 64 bit untuk nilai angka, jadi memiliki / menggunakan superkomputer tidak akan mengubah apa pun :)
Imre
untuk 0,001 Anda dapat mengganti dengan menambahkan banyak nol sesuai dengan panjang desimal. jadi ..
Miguel
15

Salah satu cara untuk menjadi 100% yakin bahwa Anda mendapatkan nomor dengan 2 desimal:

(Math.round(num*100)/100).toFixed(2)

Jika ini menyebabkan kesalahan pembulatan, Anda dapat menggunakan yang berikut seperti yang dijelaskan James dalam komentarnya:

(Math.round((num * 1000)/10)/100).toFixed(2)
Gerard de Visser
sumber
6
Ini adalah cara terbaik dan paling sederhana untuk melakukannya. Namun, karena matematika floating point, 1.275 * 100 = 127.49999999999999, yang dapat menyebabkan kesalahan kecil dalam pembulatan. Untuk memperbaikinya, kita dapat mengalikan dengan 1000 dan membaginya dengan 10, seperti (1.275 * 1000) / 10 = 127.5. Sebagai berikut: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould
(Math.round ((1.015 * 1000) / 10) / 100) .toFixed (2) masih memberikan 1,01, bukankah seharusnya 1,02?
gaurav5430
14

toFixed (n) memberikan n panjang setelah titik desimal; toPrecision (x) memberikan x total panjang.

Gunakan metode ini di bawah ini

// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
    // It will round to the tenths place
    num = 500.2349;
    result = num.toPrecision(4); // result will equal 500.2

DAN jika Anda ingin nomor diperbaiki, gunakan

result = num.toFixed(2);
Syed Umar Ahmed
sumber
itu tidak berfungsi dengan baik ... untuk angka num = 50.2349 Anda harus menulis toPrecision (3) untuk mendapatkan 50.2
Piotr Czyż
ini hanya sebuah contoh, Anda dapat mengubahnya sesuai kebutuhan Anda @ PiotrCzyż
Syed Umar Ahmed
5

Saya tidak menemukan solusi yang akurat untuk masalah ini, jadi saya buat sendiri:

function inprecise_round(value, decPlaces) {
  return Math.round(value*Math.pow(10,decPlaces))/Math.pow(10,decPlaces);
}

function precise_round(value, decPlaces){
    var val = value * Math.pow(10, decPlaces);
    var fraction = (Math.round((val-parseInt(val))*10)/10);

    //this line is for consistency with .NET Decimal.Round behavior
    // -342.055 => -342.06
    if(fraction == -0.5) fraction = -0.6;

    val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
    return val;
}

Contoh:

function inprecise_round(value, decPlaces) {
  return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

function precise_round(value, decPlaces) {
  var val = value * Math.pow(10, decPlaces);
  var fraction = (Math.round((val - parseInt(val)) * 10) / 10);

  //this line is for consistency with .NET Decimal.Round behavior
  // -342.055 => -342.06
  if (fraction == -0.5) fraction = -0.6;

  val = Math.round(parseInt(val) + fraction) / Math.pow(10, decPlaces);
  return val;
}

// This may produce different results depending on the browser environment
console.log("342.055.toFixed(2)         :", 342.055.toFixed(2)); // 342.06 on Chrome & IE10

console.log("inprecise_round(342.055, 2):", inprecise_round(342.055, 2)); // 342.05
console.log("precise_round(342.055, 2)  :", precise_round(342.055, 2));   // 342.06
console.log("precise_round(-342.055, 2) :", precise_round(-342.055, 2));  // -342.06

console.log("inprecise_round(0.565, 2)  :", inprecise_round(0.565, 2));   // 0.56
console.log("precise_round(0.565, 2)    :", precise_round(0.565, 2));     // 0.57

Florian Ignaz Eßl
sumber
2
Terima kasih. Inilah sebuah lagu pendek untuk menguji ini: jsfiddle.net/lamarant/ySXuF . Saya menerapkan toFixed () ke nilai sebelum mengembalikannya yang menambahkan jumlah nol yang benar ke akhir nilai yang dikembalikan.
Lamarant
tidak berfungsi untuk nilai = 0,004990845956707237 dan inprecise_round (nilai, 8) mengembalikan 0,00499085 tetapi harus mengembalikan 0,00499084
MERT DOĞAN
3

@heridev dan saya membuat fungsi kecil di jQuery.

Anda dapat mencoba selanjutnya:

HTML

<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​

jQuery

// apply the two-digits behaviour to elements with 'two-digits' as their class
$( function() {
    $('.two-digits').keyup(function(){
        if($(this).val().indexOf('.')!=-1){         
            if($(this).val().split(".")[1].length > 2){                
                if( isNaN( parseFloat( this.value ) ) ) return;
                this.value = parseFloat(this.value).toFixed(2);
            }  
         }            
         return this; //for chaining
    });
});

DEMO ONLINE:

http://jsfiddle.net/c4Wqn/

Vcmaster
sumber
1
Saya dapat menghargai kontribusinya, meskipun saya pikir menambahkan elemen DOM dan jQuery ke dalam campuran tampaknya keluar dari ruang lingkup pertanyaan.
Chris May
Anda tidak boleh mendengarkan acara keyup, karena terlihat sangat buruk dan tidak aktif ketika Anda menambahkan sesuatu dengan skrip. Saya lebih suka mendengarkan inputacara. Ini tidak menciptakan efek kedipan dan juga menyala saat Anda mengakses bidang dengan JS
Le 'nton
3

Masalahnya dengan nilai floating point adalah mereka mencoba untuk mewakili jumlah tak terhingga dari nilai (kontinu) dengan jumlah bit yang tetap. Jadi secara alami, pasti ada beberapa kerugian dalam permainan, dan Anda akan digigit dengan beberapa nilai.

Ketika komputer menyimpan 1.275 sebagai nilai floating point, itu tidak akan benar-benar mengingat apakah itu 1.275 atau 1.27499999999999993, atau bahkan 1.27500000000000002.0. Nilai-nilai ini harus memberikan hasil yang berbeda setelah membulatkan ke dua desimal, tetapi tidak akan, karena untuk komputer mereka terlihat sama persis setelah disimpan sebagai nilai floating point, dan tidak ada cara untuk mengembalikan data yang hilang. Setiap perhitungan lebih lanjut hanya akan mengakumulasi ketidaktepatan tersebut.

Jadi, jika presisi penting, Anda harus menghindari nilai floating point dari awal. Opsi yang paling sederhana adalah

  • gunakan perpustakaan khusus
  • gunakan string untuk menyimpan dan mengedarkan nilai-nilai (disertai dengan operasi string)
  • gunakan bilangan bulat (mis. Anda bisa memberikan sekitar seperseratus dari nilai aktual Anda, mis. jumlah dalam sen, bukan jumlah dalam dolar)

Misalnya, ketika menggunakan bilangan bulat untuk menyimpan jumlah seratus, fungsi untuk menemukan nilai sebenarnya cukup sederhana:

function descale(num, decimals) {
    var hasMinus = num < 0;
    var numString = Math.abs(num).toString();
    var precedingZeroes = '';
    for (var i = numString.length; i <= decimals; i++) {
        precedingZeroes += '0';
    }
    numString = precedingZeroes + numString;
    return (hasMinus ? '-' : '') 
        + numString.substr(0, numString.length-decimals) 
        + '.' 
        + numString.substr(numString.length-decimals);
}

alert(descale(127, 2));

Dengan string, Anda perlu pembulatan, tetapi masih dapat dikelola:

function precise_round(num, decimals) {
    var parts = num.split('.');
    var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
    var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
    var decimalPart = parts.length > 1 ? parts[1] : '';
    if (decimalPart.length > decimals) {
        var roundOffNumber = decimalPart.charAt(decimals);
        decimalPart = decimalPart.substr(0, decimals);
        if ('56789'.indexOf(roundOffNumber) > -1) {
            var numbers = integralPart + decimalPart;
            var i = numbers.length;
            var trailingZeroes = '';
            var justOneAndTrailingZeroes = true;
            do {
                i--;
                var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
                if (roundedNumber === '0') {
                    trailingZeroes += '0';
                } else {
                    numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
                    justOneAndTrailingZeroes = false;
                    break;
                }
            } while (i > 0);
            if (justOneAndTrailingZeroes) {
                numbers = '1' + trailingZeroes;
            }
            integralPart = numbers.substr(0, numbers.length - decimals);
            decimalPart = numbers.substr(numbers.length - decimals);
        }
    } else {
        for (var i = decimalPart.length; i < decimals; i++) {
            decimalPart += '0';
        }
    }
    return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

alert(precise_round('1.275', 2));
alert(precise_round('1.27499999999999993', 2));

Perhatikan bahwa fungsi ini membulatkan ke terdekat, mengikat jauh dari nol , sementara IEEE 754 merekomendasikan pembulatan ke terdekat, mengikat bahkan sebagai perilaku default untuk operasi floating point. Modifikasi semacam itu dibiarkan sebagai latihan bagi pembaca :)

Imre
sumber
3

Ini yang sederhana

function roundFloat(num,dec){
    var d = 1;
    for (var i=0; i<dec; i++){
        d += "0";
    }
    return Math.round(num * d) / d;
}

Gunakan seperti alert(roundFloat(1.79209243929,4));

Jsfiddle

ow3n
sumber
2

Bulatkan nilai desimal Anda, lalu gunakan toFixed(x)untuk angka yang Anda harapkan.

function parseDecimalRoundAndFixed(num,dec){
  var d =  Math.pow(10,dec);
  return (Math.round(num * d) / d).toFixed(dec);
}

Panggilan

parseDecimalRoundAndFixed (10.800243929,4) => 10.80 parseDecimalRoundAndFixed (10.807243929,2) => 10.81

HATCHA
sumber
2

Membulatkan ke bawah

function round_down(value, decPlaces) {
    return Math.floor(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Pembulatan

function round_up(value, decPlaces) {
    return Math.ceil(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Sekitar terdekat

function round_nearest(value, decPlaces) {
    return Math.round(value * Math.pow(10, decPlaces)) / Math.pow(10, decPlaces);
}

Digabung https://stackoverflow.com/a/7641824/1889449 dan https://www.kirupa.com/html5/rounding_numbers_in_javascript.htm Terima kasih mereka.

MERT DOĞAN
sumber
2

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some +ve edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

// testing some -ve edge cases
console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

Amr Ali
sumber
2

Inilah solusi 1-line saya: Number((yourNumericValueHere).toFixed(2));

Inilah yang terjadi:

1) Pertama, Anda menerapkan .toFixed(2)ke nomor yang Anda ingin membulatkan tempat desimal. Perhatikan bahwa ini akan mengubah nilai menjadi string dari angka. Jadi, jika Anda menggunakan TypeScript, itu akan menimbulkan kesalahan seperti ini:

"Ketik 'string' tidak dapat ditentukan untuk mengetik 'angka'"

2) Untuk mendapatkan kembali nilai numerik atau untuk mengubah string ke nilai numerik, cukup terapkan Number() fungsi pada apa yang disebut nilai 'string'.

Untuk klarifikasi, lihat contoh di bawah ini:

CONTOH: Saya memiliki jumlah yang memiliki hingga 5 digit di tempat desimal dan saya ingin mempersingkatnya menjadi hingga 2 tempat desimal. Saya melakukannya seperti ini:

var price = 0.26453;
var priceRounded = Number((price).toFixed(2));
console.log('Original Price: ' + price);
console.log('Price Rounded: ' + priceRounded);

Devner
sumber
1

Letakkan yang berikut ini di beberapa ruang lingkup global:

Number.prototype.getDecimals = function ( decDigCount ) {
   return this.toFixed(decDigCount);
}

dan kemudian coba :

var a = 56.23232323;
a.getDecimals(2); // will return 56.23

Memperbarui

Perhatikan bahwa toFixed()hanya dapat bekerja untuk jumlah desimal antara 0-20yaitu a.getDecimals(25)dapat menghasilkan kesalahan javascript, sehingga untuk mengakomodasi bahwa Anda dapat menambahkan beberapa pemeriksaan tambahan yaitu

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
Kamran Ahmed
sumber
1
Number(((Math.random() * 100) + 1).toFixed(2))

ini akan mengembalikan angka acak dari 1 hingga 100 dibulatkan ke 2 tempat desimal.

Johnathan Ralls
sumber
1

Menggunakan respons ini dengan referensi: https://stackoverflow.com/a/21029698/454827

Saya membangun fungsi untuk mendapatkan angka desimal dinamis:

function toDec(num, dec)
{
        if(typeof dec=='undefined' || dec<0)
                dec = 2;

        var tmp = dec + 1;
        for(var i=1; i<=tmp; i++)
                num = num * 10;

        num = num / 10;
        num = Math.round(num);
        for(var i=1; i<=dec; i++)
                num = num / 10;

        num = num.toFixed(dec);

        return num;
}

di sini contoh kerja: https://jsfiddle.net/wpxLduLc/

ZiTAL
sumber
1

parse = function (data) {
       data = Math.round(data*Math.pow(10,2))/Math.pow(10,2);
       if (data != null) {
            var lastone = data.toString().split('').pop();
            if (lastone != '.') {
                 data = parseFloat(data);
            }
       }
       return data;
  };

$('#result').html(parse(200)); // output 200
$('#result1').html(parse(200.1)); // output 200.1
$('#result2').html(parse(200.10)); // output 200.1
$('#result3').html(parse(200.109)); // output 200.11
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="result"></div>
<div id="result1"></div>
<div id="result2"></div>
<div id="result3"></div>

Wisnu T Asok
sumber
1

Dengan contoh-contoh ini Anda masih akan mendapatkan kesalahan saat mencoba membulatkan angka 1,005 solusinya adalah dengan menggunakan perpustakaan seperti Math.js atau fungsi ini:

function round(value: number, decimals: number) {
    return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
David Webster
sumber
1

Saya mendapat beberapa gagasan dari posting ini beberapa bulan yang lalu, tetapi tidak ada jawaban di sini, maupun jawaban dari posting / blog lain yang dapat menangani semua skenario (mis. Angka negatif dan beberapa "angka keberuntungan" yang ditemukan oleh penguji kami). Pada akhirnya, penguji kami tidak menemukan masalah dengan metode ini di bawah ini. Menempelkan cuplikan kode saya:

fixPrecision: function (value) {
    var me = this,
        nan = isNaN(value),
        precision = me.decimalPrecision;

    if (nan || !value) {
        return nan ? '' : value;
    } else if (!me.allowDecimals || precision <= 0) {
        precision = 0;
    }

    //[1]
    //return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
    precision = precision || 0;
    var negMultiplier = value < 0 ? -1 : 1;

    //[2]
    var numWithExp = parseFloat(value + "e" + precision);
    var roundedNum = parseFloat(Math.round(Math.abs(numWithExp)) + 'e-' + precision) * negMultiplier;
    return parseFloat(roundedNum.toFixed(precision));
},

Saya juga punya komentar kode (maaf saya sudah lupa semua detailnya) ... Saya memposting jawaban saya di sini untuk referensi di masa mendatang:

9.995 * 100 = 999.4999999999999
Whereas 9.995e2 = 999.5
This discrepancy causes Math.round(9.995 * 100) = 999 instead of 1000.
Use e notation instead of multiplying /dividing by Math.Pow(10,precision).
Remondo
sumber
0

Saya memperbaiki masalah pengubah. Hanya mendukung 2 desimal.

$(function(){
  //input number only.
  convertNumberFloatZero(22); // output : 22.00
  convertNumberFloatZero(22.5); // output : 22.50
  convertNumberFloatZero(22.55); // output : 22.55
  convertNumberFloatZero(22.556); // output : 22.56
  convertNumberFloatZero(22.555); // output : 22.55
  convertNumberFloatZero(22.5541); // output : 22.54
  convertNumberFloatZero(22222.5541); // output : 22,222.54

  function convertNumberFloatZero(number){
	if(!$.isNumeric(number)){
		return 'NaN';
	}
	var numberFloat = number.toFixed(3);
	var splitNumber = numberFloat.split(".");
	var cNumberFloat = number.toFixed(2);
	var cNsplitNumber = cNumberFloat.split(".");
	var lastChar = splitNumber[1].substr(splitNumber[1].length - 1);
	if(lastChar > 0 && lastChar < 5){
		cNsplitNumber[1]--;
	}
	return Number(splitNumber[0]).toLocaleString('en').concat('.').concat(cNsplitNumber[1]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

bamossza
sumber
0
(Math.round((10.2)*100)/100).toFixed(2)

Itu harus menghasilkan: 10.20

(Math.round((.05)*100)/100).toFixed(2)

Itu harus menghasilkan: 0.05

(Math.round((4.04)*100)/100).toFixed(2)

Itu harus menghasilkan: 4.04

dll.

Anthony Ruffino
sumber
0

/*Due to all told stuff. You may do 2 things for different purposes:
When showing/printing stuff use this in your alert/innerHtml= contents:
YourRebelNumber.toFixed(2)*/

var aNumber=9242.16;
var YourRebelNumber=aNumber-9000;
alert(YourRebelNumber);
alert(YourRebelNumber.toFixed(2));

/*and when comparing use:
Number(YourRebelNumber.toFixed(2))*/

if(YourRebelNumber==242.16)alert("Not Rounded");
if(Number(YourRebelNumber.toFixed(2))==242.16)alert("Rounded");

/*Number will behave as you want in that moment. After that, it'll return to its defiance.
*/

Christian Læirbag
sumber
0

Ini sangat sederhana dan berfungsi sama baiknya dengan yang lain:

function parseNumber(val, decimalPlaces) {
    if (decimalPlaces == null) decimalPlaces = 0
    var ret = Number(val).toFixed(decimalPlaces)
    return Number(ret)
}

Karena toFixed () hanya dapat dipanggil pada angka, dan sayangnya mengembalikan sebuah string, ini membuat semua parsing untuk Anda di kedua arah. Anda dapat melewati string atau angka, dan Anda mendapatkan nomor kembali setiap kali! Memanggil parseNumber (1,49) akan memberi Anda 1, dan parseNumber (1,49,2) akan memberi Anda 1,50. Sama seperti yang terbaik dari mereka!

Aaron Dake
sumber
0

Anda juga bisa menggunakan .toPrecision()metode dan beberapa kode khusus, dan selalu membulatkan ke angka desimal ke-n terlepas dari panjang bagian int.

function glbfrmt (number, decimals, seperator) {
    return typeof number !== 'number' ? number : number.toPrecision( number.toString().split(seperator)[0].length + decimals);
}

Anda juga bisa menjadikannya plugin untuk penggunaan yang lebih baik.

leo_lo
sumber
-1

Sesederhana ini.

var rounded_value=Math.round(value * 100) / 100;
Gihan Gamage
sumber
1
Salah. Coba 1.015
Marco Marsala
-2

Saya menemukan cara yang sangat sederhana yang memecahkan masalah ini untuk saya dan dapat digunakan atau diadaptasi:

td[row].innerHTML = price.toPrecision(price.toFixed(decimals).length

sumber
-4

100% berfungsi !!! Cobalah

<html>
     <head>
      <script>
      function replacePonto(){
        var input = document.getElementById('qtd');
        var ponto = input.value.split('.').length;
        var slash = input.value.split('-').length;
        if (ponto > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        if(slash > 2)
                input.value=input.value.substr(0,(input.value.length)-1);

        input.value=input.value.replace(/[^0-9.-]/,'');

        if (ponto ==2)
	input.value=input.value.substr(0,(input.value.indexOf('.')+3));

if(input.value == '.')
	input.value = "";
              }
      </script>
      </head>
      <body>
         <input type="text" id="qtd" maxlength="10" style="width:140px" onkeyup="return replacePonto()">
      </body>
    </html>

JONAS MAGALHAES DOS SANTOS
sumber
Selamat datang di SO. Silakan baca cara menjawab ini dan ikuti panduan untuk menjawab.
thewaywewere