คุณจะปัดเศษสองเท่าใน Dart ให้อยู่ในระดับความแม่นยำที่กำหนดหลังจากจุดทศนิยมได้อย่างไร


125

ให้สองเท่าฉันต้องการปัดเศษเป็นจำนวนจุดที่กำหนดหลังจุดทศนิยมคล้ายกับฟังก์ชัน round () ของ PHP

สิ่งที่ใกล้เคียงที่สุดที่ฉันสามารถพบได้ในเอกสาร Dart คือ double.toStringAsPrecision () แต่นี่ไม่ใช่สิ่งที่ฉันต้องการมากนักเพราะมันมีตัวเลขก่อนจุดทศนิยมในจุดรวมของความแม่นยำ

ตัวอย่างเช่นการใช้ toStringAsPrecision (3):

0.123456789 rounds to 0.123  
9.123456789 rounds to 9.12  
98.123456789 rounds to 98.1  
987.123456789 rounds to 987  
9876.123456789 rounds to 9.88e+3

เมื่อขนาดของตัวเลขเพิ่มขึ้นฉันจะสูญเสียความแม่นยำตามลำดับหลังจากตำแหน่งทศนิยม

คำตอบ:


208

ดูเอกสารสำหรับnum.toStringAsFixed ()

สตริงtoStringAsFixed (int เศษส่วนหลัก)

ส่งกลับการแสดงสตริงจุดทศนิยมของสิ่งนี้

แปลงค่านี้เป็นค่าสองเท่าก่อนคำนวณการแทนค่าสตริง

  • หากค่าสัมบูรณ์นี้คือมากกว่าหรือเท่ากับ 10 ^ 21 แล้วนี้วิธีการผลตอบแทนที่เป็นตัวแทนชี้แจงคำนวณโดยthis.toStringAsExponential ()

ตัวอย่าง:

1000000000000000000000.toStringAsExponential(3); // 1.000e+21
  • มิฉะนั้นผลลัพธ์คือการแทนค่าสตริงที่ใกล้เคียงที่สุดโดยมีหลักเศษส่วนตัวเลขหลังจุดทศนิยม ถ้า FractionDigits เท่ากับ 0 จุดทศนิยมจะถูกละไว้

ค่าพารามิเตอร์ fractionDigits ต้องเป็นจำนวนเต็ม: 0 <= fractionDigits <= 20

ตัวอย่าง:

1.toStringAsFixed(3);  // 1.000
(4321.12345678).toStringAsFixed(3);  // 4321.123
(4321.12345678).toStringAsFixed(5);  // 4321.12346
123456789012345678901.toStringAsFixed(3);  // 123456789012345683968.000
1000000000000000000000.toStringAsFixed(3); // 1e+21
5.25.toStringAsFixed(0); // 5

ต้องเป็นที่ยอมรับ + ​​อ้างอิง + คำอธิบาย + ตัวอย่าง
Kohls

1
ฉันเถียงคือ toStringAsFixed () วิธีการปัดเศษที่จะใช้เนื่องจากความไม่สอดคล้องกัน ตัวอย่างเช่นลอง5.550.toStringAsFixed(1)
brendan

นอกจากนี้โปรดระวังเมื่อปัดเศษเป็น 0 ตำแหน่งเนื่องจากนิพจน์จะส่งคืนค่าintแทนdoubleในกรณีนั้นเช่นหนึ่งnum.parse(50.123.toStringAsFixed(0)) is intซึ่งสามารถแก้ไขได้โดยการเพิ่ม.toDouble()ที่ส่วนท้าย
abulka

67

num.toStringAsFixed()รอบ. อันนี้จะเปลี่ยนคุณ num (n) ให้เป็นสตริงที่มีจำนวนทศนิยมที่คุณต้องการ (2) จากนั้นแยกวิเคราะห์กลับเป็น num ของคุณในโค้ดบรรทัดเดียว:

n = num.parse(n.toStringAsFixed(2));

7
นั่นเป็นวิธีที่เร็วที่สุด แต่มันโง่ที่โผไม่มีทางทำเช่นนี้โดยตรง
ThinkDigital

1
วิธีการขยาย: extension NumberRounding on num { num toPrecision(int precision) { return num.parse((this).toStringAsFixed(precision)); } }
Vit Veres

31

วิธีแก้ปัญหาข้างต้นไม่ได้ปัดเศษตัวเลขอย่างเหมาะสม ฉันใช้:

double dp(double val, int places){ 
   double mod = pow(10.0, places); 
   return ((val * mod).round().toDouble() / mod); 
}

ยืนยันแล้วรอบนี้dp(5.550, 1)ถูกต้อง5.6- ไม่เหมือนกับคำตอบยอดนิยมที่ให้คำตอบที่ไม่ถูกต้องเล็กน้อย5.5ตามที่ @brendan ชี้ไว้
abulka

ไม่ทำงานสำหรับ dp (73.4750, 2) มันส่งคืน 73.47 แทนที่จะเป็น 73.48 เครื่องคิดเลข oup.com/calculators/math/… ตรวจสอบลิงค์นี้
Deep Shah


19
void main() {
  int decimals = 2;
  int fac = pow(10, decimals);
  double d = 1.234567889;
  d = (d * fac).round() / fac;
  print("d: $d");
}

พิมพ์: 1.23


1
นี่เป็นวิธีที่ดีที่สุดในปัจจุบันในการดำเนินการนี้ การปัดเศษให้มีความแม่นยำเช่น 0.01 ซึ่งไม่ใช่การเพิ่มขึ้นสองเท่าไม่ใช่เรื่องเล็กน้อย ผลลัพธ์อาจไม่สามารถแสดงเป็นสองเท่าได้เลย ฉันขอแนะนำให้ใช้จำนวนเต็มสำหรับทุกสิ่งที่ความแม่นยำของทศนิยมมีความสำคัญ (เช่นพูดเงิน)
lrn

1
นอกจากนี้ยังควรชี้ให้เห็นว่าหากคอมไพล์เป็น js จำนวนเต็ม Dart จะเริ่มสูญเสียความแม่นยำและคุณจะต้องใช้แพ็คเกจเช่นpub.dartlang.org/packages/bignum
Greg Lowe

วิธีนี้ให้ความรู้สึกเหมือนเป็นวิธีที่ดีและสง่างามที่สุดในปัจจุบัน
Giovanni

ไม่สามารถกำหนด double ให้กับข้อผิดพลาด int เกิดขึ้นที่บรรทัด 3
Gayan Pathirage

13

ในการปัดเศษสองเท่าใน Dart ให้ได้ระดับความแม่นยำที่กำหนดหลังจากจุดทศนิยมคุณสามารถใช้โซลูชันในตัวในtoStringAsFixed()วิธีโผแต่คุณต้องแปลงกลับเป็นสองเท่า

void main() {
  double step1 = 1/3;  
  print(step1); // 0.3333333333333333
  
  String step2 = step1.toStringAsFixed(2); 
  print(step2); // 0.33 
  
  double step3 = double.parse(step2);
  print(step3); // 0.33
}


11

กำหนดส่วนขยาย:

extension Ex on double {
  double toPrecision(int n) => double.parse(toStringAsFixed(n));
}

การใช้งาน:

void main() {
  double d = 2.3456789;
  double d1 = d.toPrecision(1); // 2.3
  double d2 = d.toPrecision(2); // 2.35
  double d3 = d.toPrecision(3); // 2.345
}

10

คำตอบที่แก้ไขของ @andyw โดยใช้วิธีการขยาย Dart:

extension Precision on double {
    double toPrecision(int fractionDigits) {
        double mod = pow(10, fractionDigits.toDouble());
        return ((this * mod).round().toDouble() / mod);
    }
}

การใช้งาน:

var latitude = 1.123456;
var latitudeWithFixedPrecision = latitude.toPrecision(3); // Outputs: 1.123

8

คุณสามารถใช้toStringAsFixedเพื่อแสดงตัวเลขที่ จำกัด หลังจุดทศนิยม toStringAsFixedส่งกลับการแสดงสตริงจุดทศนิยม toStringAsFixedยอมรับอาร์กิวเมนต์ที่เรียกfraction Digitsว่าจำนวนตัวเลขหลังทศนิยมที่เราต้องการแสดง นี่คือวิธีการใช้งาน

double pi = 3.1415926;
const val = pi.toStringAsFixed(2); // 3.14

4

ฉันใช้toStringAsFixed()วิธีนี้เพื่อปัดเศษตัวเลขให้เป็นตัวเลขเฉพาะหลังจุดทศนิยม EX:

double num = 22.48132906

และเมื่อฉันปัดมันเป็นตัวเลขสองตัวดังนี้:

print(num.toStringAsFixed(2)) ;

มันพิมพ์ 22.48

และเมื่อฉันปัดเศษเป็นตัวเลขหนึ่งมันก็พิมพ์ออกมา 22.5


2

วิธีแก้ปัญหาข้างต้นใช้ไม่ได้กับทุกกรณี สิ่งที่ได้ผลสำหรับปัญหาของฉันคือวิธีแก้ปัญหานี้ที่จะปัดเศษตัวเลขของคุณ (0.5 ถึง 1 หรือ 0.49 ถึง 0) และปล่อยไว้โดยไม่มีทศนิยม :

อินพุต: 12.67

double myDouble = 12.67;
var myRoundedNumber; // Note the 'var' datatype

// Here I used 1 decimal. You can use another value in toStringAsFixed(x)
myRoundedNumber = double.parse((myDouble).toStringAsFixed(1));
myRoundedNumber = myRoundedNumber.round();

print(myRoundedNumber);

เอาต์พุต: 13

ลิงค์นี้มีวิธีแก้ปัญหาอื่น ๆ ด้วย


0

หากคุณไม่ต้องการให้ทศนิยมเมื่อทศนิยมที่ได้เป็นศูนย์ทั้งหมดสิ่งนี้จะใช้ได้:

String fixedDecimals(double d, int decimals, {bool removeZeroDecimals = true}){
  double mod = pow(10.0, decimals);
  double result = ((d * mod).round().toDouble() / mod);
  if( removeZeroDecimals && result - (result.truncate()) == 0.0 ) decimals = 0;
  return result.toStringAsFixed(decimals);
}

สิ่งนี้จะแสดงผล9แทน9.00หากอินพุตเป็น9.004และคุณต้องการทศนิยม 2 ตำแหน่ง


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