ตัดทอน (ไม่ปัดเศษ) ตัวเลขทศนิยมในจาวาสคริปต์


93

ฉันกำลังพยายามตัดทอนตัวเลขทศนิยมให้เป็นทศนิยม สิ่งนี้:

5.467   -> 5.46  
985.943 -> 985.94

toFixed(2)ไม่เกี่ยวกับสิ่งที่ถูกต้อง แต่จะปัดเศษค่า ฉันไม่ต้องการให้ค่าถูกปัดเศษ หวังว่าสิ่งนี้จะเป็นไปได้ในจาวาสคริปต์


6
jQuery เป็นเพียงกรอบและปัญหาของคุณไม่เกี่ยวข้องกับ jQuery เป็นข้อมูลเพิ่มเติมเกี่ยวกับการคำนวณพื้นฐานใน JavaScript ฉันหวังว่าคุณจะพอใจกับโซลูชันที่ไม่ใช่ jQuery
Felix Kling

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

คำตอบ:


51

อัพเดต :

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

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

[   5.467.toFixedDown(2),
    985.943.toFixedDown(2),
    17.56.toFixedDown(2),
    (0).toFixedDown(1),
    1.11.toFixedDown(1) + 22];

// [5.46, 985.94, 17.56, 0, 23.1]

โซลูชันเก่าที่เกิดข้อผิดพลาดขึ้นอยู่กับการรวบรวมผู้อื่น:

Number.prototype.toFixedDown = function(digits) {
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

4
ใช่ต้นแบบไม่ทำงานข้ามเบราว์เซอร์ได้อย่างน่าเชื่อถือ แทนที่จะกำหนดฟังก์ชั่น (วัตถุประสงค์ที่ จำกัด ) นี้ผ่านระบบ type ในลักษณะที่ทำงานไม่น่าเชื่อถือทำไมไม่ใส่ไว้ในไลบรารี
Thomas W

3
สิ่งนี้ไม่ได้ผลตามข้อยกเว้น ลองใช้หมายเลข 17.56 และหลัก = 2 ควรเป็น 17.56 แต่ฟังก์ชันนี้จะส่งกลับ 17.55
shendz

2
สองไม่สอดคล้องกับฟังก์ชั่นนี้: ฟังก์ชั่นนี้จะส่งกลับสตริงเพื่อให้1.11.toFixedDown(1) + 22ปลายขึ้นเป็นแทน1.122 23.1นอกจากนี้ยัง0.toFixedDown(1)ควรผลิตแต่มันผลิต0 -0.1
Nick Knowlson

5
โปรดทราบว่าฟังก์ชันนี้จะลบเครื่องหมายลบออก เช่น: (-10.2131).toFixedDown(2) // ==> 10.21.
rgajrawala

4
นอกจากนี้(1e-7).toFixedDown(0) // ==> 1e-7. ไม่ว่าสำหรับ1e-(>=7)(อดีต: 1e-8, 1e-9, ... )
rgajrawala

60

คำตอบของ Dogbert นั้นดี แต่ถ้ารหัสของคุณอาจต้องจัดการกับตัวเลขติดลบMath.floorด้วยตัวมันเองอาจให้ผลลัพธ์ที่ไม่คาดคิด

เช่นMath.floor(4.3) = 4แต่Math.floor(-4.3) = -5

ใช้ฟังก์ชันตัวช่วยเช่นนี้แทนเพื่อให้ได้ผลลัพธ์ที่สอดคล้องกัน:

truncateDecimals = function (number) {
    return Math[number < 0 ? 'ceil' : 'floor'](number);
};

// Applied to Dogbert's answer:
var a = 5.467;
var truncated = truncateDecimals(a * 100) / 100; // = 5.46

นี่คือเวอร์ชันที่สะดวกกว่าของฟังก์ชันนี้:

truncateDecimals = function (number, digits) {
    var multiplier = Math.pow(10, digits),
        adjustedNum = number * multiplier,
        truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);

    return truncatedNum / multiplier;
};

// Usage:
var a = 5.467;
var truncated = truncateDecimals(a, 2); // = 5.46

// Negative digits:
var b = 4235.24;
var truncated = truncateDecimals(b, -2); // = 4200

หากนั่นไม่ใช่พฤติกรรมที่ต้องการให้แทรกการโทรไปMath.absที่บรรทัดแรก:

var multiplier = Math.pow(10, Math.abs(digits)),

แก้ไข: shendz อย่างถูกต้องชี้ให้เห็นว่าการใช้วิธีนี้กับไม่ถูกต้องจะผลิตa = 17.56 17.55สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่เกิดขึ้นนี้อ่านอะไรทุกนักวิทยาศาสตร์คอมพิวเตอร์ควรรู้เกี่ยวกับจุดลอยเลขคณิต น่าเสียดายที่การเขียนวิธีแก้ปัญหาที่กำจัดแหล่งที่มาทั้งหมดของข้อผิดพลาดทศนิยมนั้นค่อนข้างยุ่งยากด้วยจาวาสคริปต์ ในภาษาอื่นคุณจะใช้จำนวนเต็มหรืออาจจะเป็นประเภททศนิยม แต่ใช้จาวาสคริปต์ ...

โซลูชันนี้ควรมีความแม่นยำ 100% แต่จะช้าลงด้วย:

function truncateDecimals (num, digits) {
    var numS = num.toString(),
        decPos = numS.indexOf('.'),
        substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
        trimmedResult = numS.substr(0, substrLength),
        finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    return parseFloat(finalResult);
}

สำหรับผู้ที่ต้องการความเร็ว แต่ยังต้องการหลีกเลี่ยงข้อผิดพลาดจุดลอยตัวลองสิ่งที่ต้องการBigDecimal.js คุณสามารถค้นหาไลบรารี javascript BigDecimal อื่น ๆ ในคำถาม SO นี้: "มีไลบรารี Javascript BigDecimal ที่ดีหรือไม่" และนี่คือบล็อกโพสต์ที่ดีเกี่ยวกับห้องสมุดคณิตศาสตร์สำหรับ Javascript


ทำไมไม่คาดคิด? การเปลี่ยนทิศทางของการปัดเศษเมื่อคุณไปต่ำกว่า 0 ทำให้เกิดสิ่งประดิษฐ์ทางคณิตศาสตร์และคณิตศาสตร์เส็งเคร็งทุกประเภท ตัวอย่างเช่นจำนวนสองเท่าจะปัดเศษเป็น 0 เป็นจำนวนเต็มอื่น ๆ สำหรับกราฟิกการบัญชีและการใช้งานอื่น ๆ อีกมากมายคุณจะได้ผลลัพธ์ที่ไม่แน่นอน ที่จะบอกความจริงกับคุณมันจะเป็นเรื่องยากที่จะพูดในสิ่งที่ข้อเสนอแนะของคุณเป็นสิ่งที่ดีสำหรับการที่จะพูดในสิ่งที่มันไม่ได้
Thomas W

เป็นสิ่งที่ดีสำหรับสิ่งที่พูด - เมื่อคุณต้องการตัดทศนิยมแทนที่จะปัดเศษ
Nick Knowlson

1
จะไม่ทำงานกับ 17.56 เนื่องจาก browser ให้ 17.56 * 100 = 1755.9999999999998 ไม่ใช่ 1756
shendz

จุดดี shendz ฉันได้อัปเดตคำตอบของฉันด้วยโซลูชันที่กำจัดข้อผิดพลาดทศนิยมทั้งหมดสำหรับผู้ที่ต้องการ
Nick Knowlson

1
สิ่งนี้จะใช้ไม่ได้กับตัวเลขที่น้อยกว่า 1 หากคุณไม่ต้องการทศนิยม - truncateDecimals (.12345, 0) จะให้ผลลัพธ์เป็น NaN เว้นแต่คุณจะเพิ่มกา: if(isNAN(result) result = 0; ขึ้นอยู่กับพฤติกรรมที่คุณต้องการ
Jeremy Witmer

35
var a = 5.467;
var truncated = Math.floor(a * 100) / 100; // = 5.46

5
สิ่งนี้ได้ผลดี แต่จะให้ผลลัพธ์ที่อาจไม่เป็นที่ต้องการหากเขา (หรือคนอื่นที่มองหาคำตอบนี้ในภายหลัง) ต้องจัดการกับตัวเลขที่เป็นลบ ดูstackoverflow.com/a/9232092/224354
Nick Knowlson

3
ทำไมไม่พึงปรารถนา? การเปลี่ยนทิศทางของการปัดเศษเมื่อคุณไปต่ำกว่า 0 ทำให้เกิดสิ่งประดิษฐ์ทางคณิตศาสตร์ทุกประเภท
Thomas W

8
มีความแตกต่างระหว่างการปัดเศษและการตัดทอน การตัดทอนเป็นพฤติกรรมที่คำถามนี้กำลังมองหาอย่างชัดเจน ถ้าฉันโทรtruncate(-3.14)และรับ-4กลับฉันจะเรียกสิ่งนั้นไม่พึงปรารถนาแน่นอน
Nick Knowlson

ฉันเห็นด้วยกับโทมัส ความแตกต่างในมุมมองอาจมาพร้อมกับว่าคุณมักจะตัดทอนเพื่อแสดงหรือเพื่อการคำนวณ จากมุมมองเชิงคำนวณสิ่งนี้หลีกเลี่ยง "สิ่งประดิษฐ์ทางคณิตศาสตร์"

3
var a = 65.1 var truncated = Math.floor(a * 100) / 100; // = 65.09 ดังนั้นนี่ไม่ใช่วิธีแก้ปัญหาที่ถูกต้อง
Sanyam Jain

22

คุณสามารถแก้ไขการปัดเศษได้โดยการลบ 0.5 สำหรับ toFixed เช่น

(f - 0.005).toFixed(2)

1
โปรดทราบ: เนื่องจากเป็นแบบนี้ใช้ไม่ได้กับตัวเลขขนาดเล็กมากตัวเลขที่มีทศนิยมมากกว่า 3 ตำแหน่งหรือตัวเลขติดลบ ลอง. 0045, 5.4678 และ -5.467
Nick Knowlson

สิ่งนี้จะใช้ได้ตราบเท่าที่คุณจับคู่ค่าที่คุณกำลังลบกับความยาวที่คุณต้องการ สิ่งที่คุณส่งไปยัง toFixed () จะต้องเป็นจำนวน 0 หลังทศนิยม
dmarra

18

พิจารณาใช้ประโยชน์จากเครื่องหมายตัวหนอนคู่:~~ .

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

function truncator(numToTruncate, intDecimalPlaces) {    
    var numPower = Math.pow(10, intDecimalPlaces); // "numPowerConverter" might be better
    return ~~(numToTruncate * numPower)/numPower;
}

ฉันพยายามที่จะต่อต้านการตัด~~สายใน parens; ฉันเชื่อว่าลำดับการดำเนินงานควรทำให้ทำงานได้อย่างถูกต้อง

alert(truncator(5.1231231, 1)); // is 5.1

alert(truncator(-5.73, 1)); // is -5.7

alert(truncator(-5.73, 0)); // is -5

การเชื่อมโยง JSFiddle

แก้ไข:เมื่อมองย้อนกลับไปฉันได้จัดการกรณีโดยไม่ได้ตั้งใจให้ปัดเศษทศนิยมออกไปทางซ้ายเช่นกัน

alert(truncator(4343.123, -2)); // gives 4300.

ตรรกะแปลกประหลาดเล็กน้อยที่กำลังมองหาการใช้งานนั้นและอาจได้รับประโยชน์จาก refactor อย่างรวดเร็ว แต่ก็ยังใช้งานได้ โชคดีกว่าดี.


นี่คือคำตอบที่ดีที่สุด หากคุณขยายMathต้นแบบด้วยสิ่งนี้และตรวจสอบ NaN-s ก่อนที่จะดำเนินการมันจะสมบูรณ์แบบ
Bartłomiej Zalewski

truncator((10 * 2.9) / 100, 2)กลับ 0.28 แทนที่จะเป็น 0.29 ... jsfiddle.net/25tgrzq1
Alex

14

โซลูชันบรรทัดเดียวที่ดี:

function truncate (num, places) {
  return Math.trunc(num * Math.pow(10, places)) / Math.pow(10, places);
}

จากนั้นโทรด้วย:

truncate(3.5636232, 2); // returns 3.56
truncate(5.4332312, 3); // returns 5.433
truncate(25.463214, 4); // returns 25.4632

2
ฉันชอบโซลูชันนี้ แต่โปรดทราบว่าเบราว์เซอร์ทั้งหมดไม่ได้รับการสนับสนุนอย่างเต็มที่ ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Gene Parcellano

11

ฉันคิดว่าฉันจะตอบโดยใช้|เพราะมันง่ายและใช้งานได้ดี

truncate = function(number, places) {
  var shift = Math.pow(10, places);

  return ((number * shift) | 0) / shift;
};

1
โทร. การใช้ตัวดำเนินการแบบบิตบังคับค่าให้เป็น int และoring ด้วย 0 หมายถึง "เก็บสิ่งที่ฉันมีอยู่แล้ว" ~~คำตอบของฉันทำอะไร แต่ด้วยการดำเนินการแบบบิตเดียว แม้ว่าจะมีข้อ จำกัด เช่นเดียวกับที่เขียนไว้เช่นกัน: เราไม่สามารถไปมากกว่า 2 ^ 31ได้
ruffin

1
ไม่ถูกต้องเมื่อtruncate((10 * 2.9) / 100);รหัสนี้ส่งคืน 0.28 แทนที่จะเป็น 0.29 jsfiddle.net/9pf0732d
Alex

@ อเล็กซ์ฉันเดาว่าคุณคงรู้ ... ยินดีต้อนรับสู่ JavaScript! . มีการแก้ไข บางทีคุณอาจต้องการแบ่งปัน? : D
ruffin

@ruffin ฉันรู้เกี่ยวกับปัญหานี้ =) ฉันคิดว่าคำตอบนี้เป็นวิธีแก้ปัญหานี้ น่าเสียดายที่ฉันยังไม่พบวิธีแก้ปัญหาที่แน่นอนทุกที่ที่มีปัญหาดังกล่าว
Alex

7

ตัดทอนโดยใช้ตัวดำเนินการแบบบิต:

~~0.5 === 0
~~(-0.5) === 0
~~14.32794823 === 14
~~(-439.93) === -439

งานนี้อ้างอิงอย่างไร: stackoverflow.com/questions/7487977/…
jperelli

มันตัดทอนบางอย่างเป็นทศนิยม 2 ตำแหน่งได้อย่างไร
Salman A

7

คำตอบของ @ Dogbert สามารถปรับปรุงได้Math.truncซึ่งจะตัดทอนแทนที่จะปัดเศษ

มีความแตกต่างระหว่างการปัดเศษและการตัดทอน การตัดทอนเป็นพฤติกรรมที่คำถามนี้กำลังมองหาอย่างชัดเจน ถ้าฉันเรียกตัดทอน (-3.14) และรับ -4 กลับฉันจะเรียกสิ่งนั้นว่าไม่พึงปรารถนาแน่นอน - @NickKnowlson

var a = 5.467;
var truncated = Math.trunc(a * 100) / 100; // = 5.46
var a = -5.467;
var truncated = Math.trunc(a * 100) / 100; // = -5.46

1
ไม่ได้ผลในทุกกรณีเช่น console.log (Math.trunc (9.28 * 100) / 100); // 9.27
Mike Makuch

@MikeMakuch ที่ไม่ได้เป็นปัญหาที่มีMath.truncแต่แทนที่จะ9.28 * 100เป็นมากกว่า927.9999 928คุณอาจต้องการอ่านเรื่องThe Perils of Floating Point
zurfyx

5

ฉันเขียนคำตอบโดยใช้วิธีที่สั้นกว่า นี่คือสิ่งที่ฉันคิดขึ้นมา

function truncate(value, precision) {
    var step = Math.pow(10, precision || 0);
    var temp = Math.trunc(step * value);

    return temp / step;
}

สามารถใช้วิธีการเช่นนั้น

truncate(132456.25456789, 5)); // Output: 132456.25456
truncate(132456.25456789, 3)); // Output: 132456.254
truncate(132456.25456789, 1)); // Output: 132456.2   
truncate(132456.25456789));    // Output: 132456

หรือถ้าคุณต้องการไวยากรณ์ที่สั้นกว่านี้คุณไปเลย

function truncate(v, p) {
    var s = Math.pow(10, p || 0);
    return Math.trunc(s * v) / s;
}

นี่เป็นวิธีที่ฉันคาดว่าจะใช้
taxilian

4
Number.prototype.trim = function(decimals) {
    var s = this.toString();
    var d = s.split(".");
    d[1] = d[1].substring(0, decimals);
    return parseFloat(d.join("."));
}

console.log((5.676).trim(2)); //logs 5.67

ฉันชอบที่มันใช้งานได้กับสตริงซึ่งจะช่วยขจัดความแตกต่างของตัวเลขทศนิยม ขอบคุณ!
iCode

4

ฉันคิดว่าฟังก์ชันนี้อาจเป็นวิธีง่ายๆ:

function trunc(decimal,n=2){
  let x = decimal + ''; // string 
  return x.lastIndexOf('.')>=0?parseFloat(x.substr(0,x.lastIndexOf('.')+(n+1))):decimal; // You can use indexOf() instead of lastIndexOf()
}

console.log(trunc(-241.31234,2));
console.log(trunc(241.312,5));
console.log(trunc(-241.233));
console.log(trunc(241.2,0));  
console.log(trunc(241));


สองปีหลังจากที่มีการโพสต์สิ่งนี้ แต่สะดุดกับสิ่งนี้เมื่อฉันพยายามหาวิธีที่ดีที่สุดโดยใช้ Math.trunc, regex และอื่น ๆ ฉันชอบวิธีนี้มาก ตายง่าย แต่ใช้งานได้ดี (สำหรับกรณีการใช้งานของฉันอยู่ดี)
giles123

อย่าลืมบัญชีสำหรับ n = 0 ด้วย
giles123

3

ฉันพบปัญหา: พิจารณาสถานการณ์ถัดไป: 2.1 หรือ 1.2 หรือ -6.4

จะเป็นอย่างไรถ้าคุณต้องการ 3 ทศนิยมหรือสองหรือ wharever เสมอดังนั้นคุณต้องเติมเลขศูนย์นำหน้าทางด้านขวา

// 3 decimals numbers
0.5 => 0.500

// 6 decimals
0.1 => 0.10000

// 4 decimales
-2.1 => -2.1000

// truncate to 3 decimals
3.11568 => 3.115

นี่คือฟังก์ชันคงที่ของ Nick Knowlson

function truncateDecimals (num, digits) 
{
    var numS = num.toString();
    var decPos = numS.indexOf('.');
    var substrLength = decPos == -1 ? numS.length : 1 + decPos + digits;
    var trimmedResult = numS.substr(0, substrLength);
    var finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;

    // adds leading zeros to the right
    if (decPos != -1){
        var s = trimmedResult+"";
        decPos = s.indexOf('.');
        var decLength = s.length - decPos;

            while (decLength <= digits){
                s = s + "0";
                decPos = s.indexOf('.');
                decLength = s.length - decPos;
                substrLength = decPos == -1 ? s.length : 1 + decPos + digits;
            };
        finalResult = s;
    }
    return finalResult;
};

https://jsfiddle.net/huttn155/7/


x = 0.0000การทดสอบtruncateDecimals (x, 2)ล้มเหลว 0ผลตอบแทน ไม่เป็นไปตามคาด0.00
Ling Loeng

3
function toFixed(number, digits) {
    var reg_ex = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)")
    var array = number.toString().match(reg_ex);
    return array ? parseFloat(array[1]) : number.valueOf()
}

var test = 10.123456789
var __fixed = toFixed(test, 6)
console.log(__fixed)
// => 10.123456

3

คำตอบของ @kirilloid ดูเหมือนจะเป็นคำตอบที่ถูกต้องอย่างไรก็ตามต้องมีการอัปเดตรหัสหลัก วิธีแก้ปัญหาของเขาไม่ได้ดูแลตัวเลขเชิงลบ (ซึ่งมีคนพูดถึงในส่วนความคิดเห็น แต่ยังไม่ได้รับการอัปเดตในรหัสหลัก)

การอัปเดตเป็นโซลูชันการทดสอบขั้นสุดท้ายที่สมบูรณ์:

Number.prototype.toFixedDown = function(digits) {
    var re = new RegExp("([-]*\\d+\\.\\d{" + digits + "})(\\d)"),
    m = this.toString().match(re);
    return m ? parseFloat(m[1]) : this.valueOf();
};

การใช้งานตัวอย่าง:

var x = 3.1415629;
Logger.log(x.toFixedDown(2)); //or use whatever you use to log

Fiddle: JS Number ปัดเศษลง

PS: มี repo ไม่เพียงพอที่จะแสดงความคิดเห็นเกี่ยวกับโซลูชันนั้น


2

นี่คือฟังก์ชั่นที่เรียบง่าย แต่ใช้งานได้เพื่อตัดทอนจำนวนทศนิยมไม่เกิน 2 ตำแหน่ง

           function truncateNumber(num) {
                var num1 = "";
                var num2 = "";
                var num1 = num.split('.')[0];
                num2 = num.split('.')[1];
                var decimalNum = num2.substring(0, 2);
                var strNum = num1 +"."+ decimalNum;
                var finalNum = parseFloat(strNum);
                return finalNum;
            }

2

ประเภทผลลัพธ์ยังคงเป็นตัวเลข ...

/* Return the truncation of n wrt base */
var trunc = function(n, base) {
    n = (n / base) | 0;
    return base * n;
};
var t = trunc(5.467, 0.01);

2

Lodash มีไม่กี่วิธีคณิตศาสตร์ยูทิลิตี้ที่สามารถรอบ , พื้นและceilจำนวนความแม่นยำทศนิยมที่กำหนด สิ่งนี้ทำให้ไม่มีศูนย์ต่อท้าย

พวกเขาใช้แนวทางที่น่าสนใจโดยใช้เลขชี้กำลังของจำนวน เห็นได้ชัดว่าสิ่งนี้หลีกเลี่ยงปัญหาการปัดเศษ

(หมายเหตุ: funcคือMath.roundหรือceilหรือfloorในรหัสด้านล่าง)

// Shift with exponential notation to avoid floating-point issues.
var pair = (toString(number) + 'e').split('e'),
    value = func(pair[0] + 'e' + (+pair[1] + precision));

pair = (toString(value) + 'e').split('e');
return +(pair[0] + 'e' + (+pair[1] - precision));

ลิงก์ไปยังซอร์สโค้ด


1

นี่คือสิ่งที่ฉันทำในหัวข้อ:

convert.truncate = function(value, decimals) {
  decimals = (decimals === undefined ? 0 : decimals);
  return parseFloat((value-(0.5/Math.pow(10, decimals))).toFixed(decimals),10);
};

เป็นเพียงเวอร์ชันที่ซับซ้อนกว่าเล็กน้อยของไฟล์

(f - 0.005).toFixed(2)

1

สิ่งที่ทำเครื่องหมายว่าเป็นโซลูชันคือทางออกที่ดีกว่าที่ฉันพบจนถึงวันนี้ แต่มีปัญหาร้ายแรงกับ 0 (เช่น 0.toFixedDown (2) ให้ -0.01) ดังนั้นฉันขอแนะนำให้ใช้สิ่งนี้:

Number.prototype.toFixedDown = function(digits) {
  if(this == 0) {
    return 0;
  }
  var n = this - Math.pow(10, -digits)/2;
  n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
  return n.toFixed(digits);
}

1

นี่คือสิ่งที่ฉันใช้:

var t = 1;
for (var i = 0; i < decimalPrecision; i++)
    t = t * 10;

var f = parseFloat(value);
return (Math.floor(f * t)) / t;

1
const TO_FIXED_MAX = 100;

function truncate(number, decimalsPrecison) {
  // make it a string with precision 1e-100
  number = number.toFixed(TO_FIXED_MAX);

  // chop off uneccessary digits
  const dotIndex = number.indexOf('.');
  number = number.substring(0, dotIndex + decimalsPrecison + 1);

  // back to a number data type (app specific)
  return Number.parseFloat(number);
}

// example
truncate(0.00000001999, 8);
0.00000001

ทำงานร่วมกับ:

  • จำนวนลบ
  • ตัวเลขน้อยมาก (Number.EPSILON precision)

0

เพียงเพื่อชี้ให้เห็นวิธีง่ายๆที่ได้ผลสำหรับฉัน

แปลงเป็นสตริงแล้ว regex ...

var number = 123.45678;
var number_s = '' + number;
var number_truncated_s = number_s.match(/\d*\.\d{4}/)[0]
var number_truncated = parseFloat(number_truncated_s)

สามารถย่อเป็น

var number_truncated = parseFloat(('' + 123.4568908).match(/\d*\.\d{4}/)[0])

0

นี่คือรหัส ES6 ที่ทำในสิ่งที่คุณต้องการ

const truncateTo = (unRouned, nrOfDecimals = 2) => {
      const parts = String(unRouned).split(".");

      if (parts.length !== 2) {
          // without any decimal part
        return unRouned;
      }

      const newDecimals = parts[1].slice(0, nrOfDecimals),
        newString = `${parts[0]}.${newDecimals}`;

      return Number(newString);
    };

// your examples 

 console.log(truncateTo(5.467)); // ---> 5.46

 console.log(truncateTo(985.943)); // ---> 985.94

// other examples 

 console.log(truncateTo(5)); // ---> 5

 console.log(truncateTo(-5)); // ---> -5

 console.log(truncateTo(-985.943)); // ---> -985.94



0

คุณสามารถทำงานกับสตริง ตรวจสอบว่า "." มีอยู่แล้วลบบางส่วนของสตริง

ตัดทอน (7.88, 1) -> 7.8

ตัดทอน (7.889, 2) -> 7.89

ตัดทอน (-7.88, 1) -> -7.88

function  truncate(number, decimals) {
    const tmp = number + '';
    if (tmp.indexOf('.') > -1) {
        return +tmp.substr(0 , tmp.indexOf('.') + decimals+1 );
    } else {
        return +number
    }
 }

0

ฉันสับสนเล็กน้อยว่าทำไมถึงมีคำตอบที่แตกต่างกันมากมายสำหรับคำถามง่ายๆเช่นนี้ มีเพียงสองวิธีที่ฉันเห็นซึ่งดูเหมือนจะคุ้มค่า ฉันทำการเปรียบเทียบอย่างรวดเร็วเพื่อดูความแตกต่างของความเร็วโดยใช้https://jsbench.me/ https://jsbench.me/

นี่คือคำตอบซึ่งปัจจุบัน (9/26/2020) ถูกตั้งค่าสถานะเป็นคำตอบ:

function truncate(n, digits) {
    var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
        m = n.toString().match(re);
    return m ? parseFloat(m[1]) : n.valueOf();
};

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];

อย่างไรก็ตามนี่เป็นการทำสิ่งที่เป็นสตริงและ regex ซึ่งโดยปกติจะไม่มีประสิทธิภาพมากนักและมีฟังก์ชัน Math.trunc ที่ทำอย่างแน่นอนที่ OP ต้องการโดยไม่มีทศนิยม ดังนั้นคุณสามารถใช้มันบวกเลขคณิตพิเศษเล็กน้อยเพื่อให้ได้สิ่งเดียวกัน

นี่เป็นอีกวิธีหนึ่งที่ฉันพบในเธรดนี้ซึ่งเป็นวิธีที่ฉันจะใช้:

function truncate(n, digits) {
    var step = Math.pow(10, digits || 0);
    var temp = Math.trunc(step * n);

    return temp / step;
}

[   truncate(5.467,2),
    truncate(985.943,2),
    truncate(17.56,2),
    truncate(0, 1),
    truncate(1.11, 1) + 22];
    

วิธีแรกช้ากว่าวิธีที่สอง 99.92% ดังนั้นวิธีที่สองแน่นอนหนึ่งที่ผมจะแนะนำให้ใช้

เอาล่ะกลับไปหาวิธีเลี่ยงงานอื่น ...

ภาพหน้าจอของเกณฑ์มาตรฐาน

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