การจัดรูปแบบตัวเลขด้วยทศนิยมสองตำแหน่งใน JavaScript


571

ฉันมีรหัสบรรทัดนี้ซึ่งปัดเศษตัวเลขเป็นทศนิยมสองตำแหน่ง แต่ฉันได้รับตัวเลขเช่นนี้: 10.8, 2.4, ฯลฯ นี่ไม่ใช่ความคิดของฉันเกี่ยวกับทศนิยมสองตำแหน่งดังนั้นฉันจะปรับปรุงสิ่งต่อไปนี้ได้อย่างไร

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

ฉันต้องการตัวเลขเช่น 10.80, 2.40 เป็นต้นการใช้ jQuery ใช้ได้กับฉัน


1
รหัสของคุณคือสิ่งที่ฉันกำลังมองหา (เพื่อลดความแม่นยำในการลอยตัวให้เหลือทศนิยม 7 ตำแหน่งสำหรับไฟล์ JSON ขนาดเล็ก) การข้าม Math.pow สำหรับ speed val = Math.round (val * 10,000000) / 10,000000);
Pawel

ในฐานะที่เป็นคำตอบในปัจจุบันได้รับการยอมรับให้เนื้อหาที่เป็นผลที่ไม่ถูกต้องสำหรับช่วงกว้างของค่าขอบคุณที่เหตุความไม่แน่ชัดอยู่ในตัวเลข ( 0.565, 0.575, 1.005) ผมสามารถแนะนำให้ดูอีกครั้งที่คำตอบนี้ซึ่งพวกเขาได้รับการแก้ไข?
TJ Crowder

บางทีคุณอาจต้องการที่จะรวมไลบรารี sprintf สำหรับ JavaScript stackoverflow.com/questions/610406/ …
Thilo

หลังจากปัดเศษทศนิยมด้วยวิธีการเลื่อนและการปัดเศษทศนิยมอย่างถูกต้องแล้วคุณสามารถใช้number.toFixed(x)วิธีการแปลงเป็นสตริงด้วยจำนวนศูนย์ที่ต้องการ เช่นปัด1.34ไป1.3ด้วยเมธอดข้ามเบราว์เซอร์แล้วเพิ่ม 1 ศูนย์และแปลงเป็นสตริงด้วย1.3.toFixed(2)(เพื่อรับ"1.30")
Edward

คำตอบ:


999

ในการจัดรูปแบบตัวเลขโดยใช้เครื่องหมายจุดคงที่คุณสามารถใช้วิธีtoFixed :

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

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

โปรดทราบว่าtoFixed()ส่งกลับสตริง

สิ่งสำคัญ : โปรดทราบว่า toFixed ไม่ได้รอบ 90% ของเวลามันจะกลับค่าปัดเศษ แต่สำหรับหลายกรณีมันไม่ทำงาน

ตัวอย่างเช่น

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

UPDATE:

ทุกวันนี้คุณสามารถใช้ตัวIntl.NumberFormatสร้าง เป็นส่วนหนึ่งของข้อกำหนดคุณลักษณะECMAScript Internationalization API (ECMA402) แต่ก็มีการสนับสนุนเบราว์เซอร์ที่ดีงามที่รวมถึง IE11 และจะได้รับการสนับสนุนอย่างเต็มที่ในการ 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"

คุณสามารถเลือกใช้toLocaleStringวิธีการซึ่งจะใช้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 นี้ยังมีตัวเลือกในการจัดรูปแบบที่หลากหลายเช่นตัวคั่นหลักพันสัญลักษณ์สกุลเงินเป็นต้น


17
ไม่สามารถใช้งานได้กับเบราว์เซอร์ทั้งหมดอย่างสม่ำเสมอเช่น(0.09).toFixed(1);ให้ 0.0 ใน IE8
ajbeaven

41
คงไม่รอบคุณสามารถทำได้ก่อน: (Math.round (0.09)) toFixed (1);
rekans

32
@rekans: นี่มันผิด Math.Round(0.09)จะกลับมา0ดังนั้นนี้มักจะให้0.0...
คริส

28
นี่เป็นความคิดที่ไม่ดีในสถานการณ์ส่วนใหญ่มันจะแปลงตัวเลขเป็นสตริงหรือจำนวนจุดลอยตัวในบางกรณี
Ash Blue

80
ต้องเห็นด้วยกับ @AshBlue ที่นี่ ... นี่เป็นเพียงความปลอดภัยสำหรับการจัดรูปแบบการนำเสนอค่า อาจแบ่งรหัสด้วยการคำนวณเพิ่มเติม มิฉะนั้นจะMath.round(value*100)/100ทำงานได้ดีกว่าสำหรับ 2DP
UpTheCreek

98

นี่เป็นหัวข้อเก่า แต่ยังคงเป็นผลลัพธ์ของ Google ที่ติดอันดับต้น ๆ และโซลูชันที่นำเสนอจะแบ่งปันประเด็นทศนิยมแบบเดียวกัน นี่คือฟังก์ชัน (ทั่วไปมาก) ที่ฉันใช้ด้วย 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));
}

อย่างที่เราเห็นเราไม่ได้รับปัญหาเหล่านี้:

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

genericity นี้ยังให้สิ่งดีๆบางอย่าง:

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

ตอนนี้เพื่อตอบคำถามของ OP ต้องพิมพ์:

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

หรือสำหรับฟังก์ชันทั่วไปที่กระชับน้อยกว่า:

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

คุณสามารถโทรหาด้วย:

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

ตัวอย่างและการทดสอบต่างๆ (ขอบคุณ@ tj-crowder !):


1
ไม่มีวิธีง่ายๆในการทำเช่นนี้อย่างไร ES6 เพื่อช่วยเหลือ?
zero_cool

ขอบคุณที่โพสต์ polyfill MDN บนหน้า MDN ที่เชื่อมโยง polyfill จะไม่อยู่ที่นั่นอีกต่อไป ฉันสงสัยว่าทำไมมันถึงถูกลบ ...
King Holly

43

ฉันมักจะเพิ่มสิ่งนี้ลงในห้องสมุดส่วนตัวของฉันและหลังจากคำแนะนำและการใช้โซลูชัน @TIMINeutron ด้วยและทำให้มันปรับได้ตามความยาวทศนิยมแล้วอันนี้เหมาะที่สุด:

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

จะทำงานให้กับข้อยกเว้นที่รายงาน


2
precision_round (1.275,2) คือ 1.27?
allenhwkim

2
@Imre เปลี่ยนค่าที่ส่งคืนเป็น (Math.round (จำนวน * Math.pow (10, ทศนิยม)) / Math.pow (10, ทศนิยม) เพื่อคงที่ (2); และคุณจะไม่มีปัญหานั้นอีกต่อไป
dkroy

6
คุณจะประกาศว่า "sign" และ "dec" อยู่ที่ไหนถ้าฟังก์ชั่นที่สองของคุณถูกหยิบขึ้นมาเหมือนที่มันไม่ควรให้มันเป็น undefined?
Ady Ngom

2
ฉันได้เพิ่มการหลีกเลี่ยงปัญหาสำหรับวิธีลงชื่อเข้าใช้ missign ใน IE: gist.github.com/ArminVieweg/28647e735aa6efaba401
Armin

1
@Armin การแก้ไขของคุณยังทำงานได้ใน Safari ฟังก์ชั่นดั้งเดิมไม่ทำงานใน Safari
เดฟ

19

ฉันไม่รู้ว่าทำไมฉันไม่สามารถเพิ่มความคิดเห็นไปยังคำตอบก่อนหน้า (บางทีฉันอาจจะตาบอด, dunno) แต่ฉันคิดวิธีแก้ปัญหาโดยใช้คำตอบของ @ Miguel:

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

และความคิดเห็นสองรายการ (จาก @bighostkim และ @Imre):

  • ปัญหาเกี่ยวกับการprecise_round(1.275,2)ไม่คืนค่า 1.28
  • ปัญหาprecise_round(6,2)ไม่คืน 6.00 (ตามที่เขาต้องการ)

ทางออกสุดท้ายของฉันมีดังนี้:

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

อย่างที่คุณเห็นฉันต้องเพิ่ม "การแก้ไข" เล็กน้อย (ไม่ใช่สิ่งที่มันเป็น แต่เนื่องจาก Math.round สูญเสียคุณสามารถตรวจสอบได้ที่ jsfiddle.net - นี่เป็นวิธีเดียวที่ฉันรู้วิธี "แก้ไข "มัน) มันเพิ่ม 0.001 ไปยังตัวเลขที่มีเบาะแล้วดังนั้นมันจึงเพิ่ม1สาม0s ทางด้านขวาของค่าทศนิยม ดังนั้นควรใช้อย่างปลอดภัย

หลังจากนั้นฉันเพิ่ม.toFixed(decimal)เพื่อเอาท์พุทตัวเลขในรูปแบบที่ถูกต้องเสมอ (ด้วยจำนวนทศนิยมที่เหมาะสม)

ดังนั้นมันสวยมาก ใช้งานได้ดี;)

แก้ไข: เพิ่มฟังก์ชันการทำงานให้กับ "การแก้ไข" ของจำนวนลบ


2
"การแก้ไข" นั้นส่วนใหญ่จะปลอดภัย แต่precise_round(1.27499,2)ตอนนี้กลับมาที่ 1.28 ... นั่นไม่ใช่การMath.roundสูญเสีย วิธีที่คอมพิวเตอร์เก็บค่าจุดลอยตัวภายใน โดยทั่วไปคุณกำลังถึงวาระที่จะล้มเหลวด้วยค่าบางอย่างก่อนที่ข้อมูลแม้ได้รับการทำงานของคุณ :)
แฟลเลิ

@ ฉันกำลังคุณอย่างแน่นอน นั่นเป็นเหตุผลที่ฉันอธิบายสิ่งนี้ที่ 0.001 ทำในกรณีที่ใครต้องการทำให้ " แม่นยำมากขึ้น" หรือลบมัน (ถ้าคุณมีคอมพิวเตอร์สุดยอดที่มี 2 Mbytes ต่อโฟลฉันไม่คิดว่าใครที่นี่จะทำ ;)
tfrascaroli

1
ที่จริงแล้วสเปคภาษาเป็นเฉพาะสวยเกี่ยวกับการใช้ 64 บิตสำหรับค่าตัวเลขเพื่อให้มี / ใช้ซูเปอร์คอมพิวเตอร์จะไม่เปลี่ยนแปลงอะไร :)
แฟลเลิ

สำหรับ 0.001 คุณสามารถแทนที่ได้ด้วยการเพิ่มศูนย์จำนวนมากตามความยาวของทศนิยม ดังนั้น ..
มิเกล

15

วิธีหนึ่งที่จะแน่ใจได้ 100% ว่าคุณได้รับตัวเลขด้วยทศนิยม 2 ตำแหน่ง:

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

หากนี่เป็นสาเหตุของข้อผิดพลาดในการปัดเศษคุณสามารถใช้สิ่งต่อไปนี้ตามที่ James อธิบายไว้ในความคิดเห็นของเขา

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

6
นี่เป็นวิธีที่ดีที่สุดและง่ายที่สุดในการทำ อย่างไรก็ตามเนื่องจากคณิตศาสตร์จุดลอยตัว 1.275 * 100 = 127.49999999999999 ซึ่งอาจทำให้เกิดข้อผิดพลาดเล็กน้อยในการปัดเศษ ในการแก้ปัญหานี้เราสามารถคูณ 1,000 และหารด้วย 10 ตาม (1.275 * 1,000) / 10 = 127.5 ดังนี้: var answer = (Math.round((num * 1000)/10)/100).toFixed(2);
James Gould

(Math.round ((1.015 * 1,000) / 10) / 100) .Fixed (2) ยังคงให้ 1.01 มันควรจะเป็น 1.02 หรือไม่?
gaurav5430

14

toFixed (n) ให้ความยาว n หลังจากจุดทศนิยม toPrecision (x) ให้ความยาวทั้งหมด x

ใช้วิธีนี้ด้านล่าง

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

และถ้าคุณต้องการให้หมายเลขถูกใช้คงที่

result = num.toFixed(2);

มันใช้งานไม่ได้ ... สำหรับ number num = 50.2349 คุณควรเขียน toPrecision (3) เพื่อรับ 50.2
Piotr Czyż

มันเป็นเพียงตัวอย่างที่คุณสามารถเปลี่ยนได้ตามความต้องการของคุณ @ PiotrCzyż
Syed Umar Ahmed

5

ฉันไม่พบวิธีแก้ไขปัญหาที่ถูกต้องสำหรับปัญหานี้ดังนั้นฉันจึงสร้างของตัวเอง:

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

ตัวอย่าง:

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


2
ขอบคุณ นี่เป็นเพลงสั้น ๆ ในการทดสอบนี้: jsfiddle.net/lamarant/ySXuF ฉันใช้ toFixed () กับค่าก่อนที่จะคืนค่าซึ่งผนวกเลขศูนย์ที่ถูกต้องต่อท้ายค่าที่ส่งคืน
lamarant

ไม่ทำงานสำหรับค่า = 0,004990845956707237 และ inprecise_round (ค่า 8) ส่งคืน 0,00499085 แต่จะต้องส่งคืน 0,00499084
MERT DOĞAN

3

@heridev และฉันสร้างฟังก์ชั่นเล็ก ๆ ใน jQuery

คุณสามารถลองต่อไป:

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

สาธิตออนไลน์:

http://jsfiddle.net/c4Wqn/


1
ฉันสามารถชื่นชมการสนับสนุนแม้ว่าฉันคิดว่าการเพิ่มองค์ประกอบ DOM และ jQuery ลงในส่วนประสมนั้นดูเหมือนจะไม่ครอบคลุมคำถาม
Chris พฤษภาคม

คุณไม่ควรฟังเหตุการณ์ keyup เพราะมันดูแย่มากและไม่เปิดใช้งานเมื่อคุณเพิ่มบางอย่างด้วยสคริปต์ ฉันอยากฟังinputเหตุการณ์ สิ่งนี้ไม่สร้างเอฟเฟกต์กะพริบและไฟเมื่อคุณเข้าถึงฟิลด์ด้วย JS
Le 'nton

3

ปัญหาของค่าทศนิยมคือว่าพวกเขากำลังพยายามที่จะแสดงจำนวนอนันต์ของค่า (ต่อเนื่อง) ด้วยจำนวนบิตคงที่ ดังนั้นโดยธรรมชาติจะต้องมีการสูญเสียในการเล่นและคุณจะถูกกัดด้วยค่าบางอย่าง

เมื่อคอมพิวเตอร์เก็บค่า 1.275 เป็นค่าทศนิยมนั้นจริง ๆ แล้วจะไม่จดจำว่าเป็น 1.275 หรือ 1.2749999999999999993 หรือแม้กระทั่ง 1.27500000000000002 ค่าเหล่านี้ควรให้ผลลัพธ์ที่แตกต่างกันหลังจากการปัดเศษเป็นทศนิยมสองตำแหน่ง แต่จะไม่เนื่องจากคอมพิวเตอร์จะมีค่าเหมือนกันหลังจากเก็บเป็นค่าทศนิยมและไม่มีวิธีการกู้คืนข้อมูลที่สูญหาย การคำนวณเพิ่มเติมใด ๆ จะสะสมความไม่แน่นอนดังกล่าวเท่านั้น

ดังนั้นหากความแม่นยำมีความสำคัญคุณต้องหลีกเลี่ยงค่าจุดลอยตัวตั้งแต่ต้น ตัวเลือกที่ง่ายที่สุดคือ

  • ใช้ห้องสมุดที่ทุ่มเท
  • ใช้สตริงสำหรับการจัดเก็บและการส่งค่าต่างๆ
  • ใช้จำนวนเต็ม (เช่นคุณอาจผ่านจำนวนร้อยของมูลค่าจริงของคุณเช่นจำนวนเงินในเซนต์แทนจำนวนเงินเป็นดอลลาร์)

ตัวอย่างเช่นเมื่อใช้จำนวนเต็มเพื่อเก็บจำนวนหนึ่งร้อยฟังก์ชั่นสำหรับค้นหาค่าจริงนั้นค่อนข้างง่าย:

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

ด้วยสตริงคุณจะต้องปัดเศษ แต่ก็ยังจัดการได้:

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

โปรดทราบว่าฟังก์ชั่นนี้รอบที่ใกล้ที่สุดความสัมพันธ์ห่างจากศูนย์ในขณะที่อีอีอี 754แนะนำปัดเศษที่ใกล้ที่สุด, ความสัมพันธ์ที่จะได้เป็นพฤติกรรมเริ่มต้นสำหรับการดำเนินงานจุดลอย การดัดแปลงดังกล่าวจะถูกปล่อยไว้เป็นแบบฝึกหัดสำหรับผู้อ่าน :)


3

นี่เป็นวิธีง่ายๆ

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

ใช้เหมือน alert(roundFloat(1.79209243929,4));

Jsfiddle


2

ปัดเศษทศนิยมของคุณจากนั้นใช้toFixed(x)สำหรับตัวเลขที่คุณคาดหวัง

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

โทร

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


2

ปัดลง

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

ปัดขึ้น

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

รอบที่ใกล้ที่สุด

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

ผสานhttps://stackoverflow.com/a/7641824/1889449และ https://www.kirupa.com/html5/rounding_numbers_in_javascript.htmขอบคุณพวกเขา


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


2

นี่คือโซลูชัน 1 บรรทัดของฉัน: Number((yourNumericValueHere).toFixed(2));

นี่คือสิ่งที่เกิดขึ้น:

1) ขั้นแรกคุณใช้.toFixed(2)หมายเลขที่คุณต้องการปัดเศษทศนิยม โปรดทราบว่าสิ่งนี้จะแปลงค่าเป็นสตริงจากตัวเลข ดังนั้นหากคุณใช้ typescript มันจะโยนข้อผิดพลาดเช่นนี้:

"Type 'string' ไม่สามารถกำหนดให้พิมพ์ 'number'"

2) ในการเรียกคืนค่าตัวเลขหรือแปลงสตริงเป็นค่าตัวเลขเพียงแค่ใช้Number()ฟังก์ชั่นกับค่าที่เรียกว่า 'สตริง'

สำหรับการชี้แจงให้ดูตัวอย่างด้านล่าง:

ตัวอย่าง: ฉันมีจำนวนที่มีตัวเลขไม่เกิน 5 หลักในตำแหน่งทศนิยมและฉันต้องการย่อให้เหลือไม่เกิน 2 ตำแหน่ง ฉันทำเช่นนั้น:

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


1

วางต่อไปนี้ในขอบเขตโกลบอล:

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

และแล้วลอง :

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

ปรับปรุง

โปรดทราบว่าtoFixed()สามารถทำงานได้เฉพาะกับจำนวนทศนิยมระหว่าง0-20เช่นa.getDecimals(25)อาจสร้างข้อผิดพลาดจาวาสคริปต์ดังนั้นเพื่อรองรับว่าคุณอาจเพิ่มการตรวจสอบเพิ่มเติมบางอย่างเช่น

Number.prototype.getDecimals = function ( decDigCount ) {
   return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}

1
Number(((Math.random() * 100) + 1).toFixed(2))

จะส่งคืนตัวเลขสุ่มจาก 1 ถึง 100 ปัดเศษเป็นทศนิยม 2 ตำแหน่ง



1

ใช้การตอบสนองนี้โดยอ้างอิง: https://stackoverflow.com/a/21029698/454827

ฉันสร้างฟังก์ชันเพื่อรับจำนวนทศนิยมแบบไดนามิก:

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

ตัวอย่างการทำงานที่นี่: https://jsfiddle.net/wpxLduLc/


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>


1

ด้วยตัวอย่างเหล่านี้คุณจะยังคงได้รับข้อผิดพลาดเมื่อพยายามปัดเศษตัวเลข 1.005 วิธีแก้ไขคือใช้ไลบรารีเช่น Math.js หรือฟังก์ชันนี้:

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

1

ฉันได้รับแนวคิดจากโพสต์นี้เมื่อไม่กี่เดือนที่ผ่านมา แต่ไม่มีคำตอบใด ๆ ที่นี่ไม่มีคำตอบจากโพสต์ / บล็อกอื่น ๆ ที่สามารถจัดการกับทุกสถานการณ์ (เช่นตัวเลขติดลบและพบ "ผู้โชคดี" ผู้ทดสอบของเรา) ในที่สุดผู้ทดสอบของเราไม่พบปัญหาใด ๆ กับวิธีนี้ด้านล่าง วางตัวอย่างรหัสของฉัน:

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

ฉันยังมีความคิดเห็นรหัส (ขออภัยฉันลืมรายละเอียดทั้งหมดแล้ว) ... ฉันโพสต์คำตอบของฉันที่นี่เพื่อการอ้างอิงในอนาคต:

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

0

ฉันแก้ไขปัญหาตัวแก้ไข รองรับทศนิยม 2 ตำแหน่งเท่านั้น

$(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>


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

ที่ควรจะให้: 10.20

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

ที่ควรจะให้: 0.05

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

ที่ควรจะให้: 4.04

เป็นต้น


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


0

มันง่ายมากและใช้งานได้เช่นเดียวกับสิ่งอื่น ๆ :

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

เนื่องจาก toFixed () สามารถโทรได้ที่ตัวเลขเท่านั้นและโชคไม่ดีที่ส่งคืนสตริงสิ่งนี้จะแยกวิเคราะห์ให้คุณทั้งสองทิศทาง คุณสามารถส่งผ่านสตริงหรือตัวเลขและคุณจะได้รับหมายเลขกลับทุกครั้ง! การโทร parseNumber (1.49) จะให้ 1 และ parseNumber (1.49,2) จะให้คุณ 1.50 เช่นเดียวกับที่สุดของ 'em!


0

นอกจากนี้คุณยังสามารถใช้ .toPrecision()วิธีการและรหัสที่กำหนดเองบางส่วนและปัดเศษขึ้นเป็นตัวเลขทศนิยมที่ n โดยไม่คำนึงถึงความยาวของส่วน int

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

คุณสามารถทำให้มันเป็นปลั๊กอินสำหรับการใช้งานที่ดีขึ้น



-2

ฉันพบวิธีง่าย ๆ ที่แก้ไขปัญหานี้ให้ฉันและสามารถนำไปใช้หรือดัดแปลง:

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

-4

ทำงาน 100% !!! ลองมัน

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


ยินดีต้อนรับสู่ SO โปรดอ่านวิธีการตอบและปฏิบัติตามแนวทางที่จะตอบ
2560
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.