Jak zaokrąglić podwójną w Dart do określonego stopnia dokładności PO przecinku?

125

Biorąc pod uwagę wartość podwójną, chcę zaokrąglić ją do określonej liczby dokładnych punktów po przecinku , podobnie jak w funkcji round () w PHP.

Najbliższą rzeczą, jaką mogę znaleźć w dokumentach Dart, jest double.toStringAsPrecision (), ale nie jest to do końca to, czego potrzebuję, ponieważ zawiera cyfry przed kropką dziesiętną w łącznej liczbie punktów dokładności.

Na przykład, używając 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

Wraz ze wzrostem wielkości liczby odpowiednio tracę precyzję po przecinku.

Lucas Meadows
źródło

Odpowiedzi:

207

Zobacz dokumentację num.toStringAsFixed () .

Ciąg toStringAsFixed (int fractionDigits)

Zwraca reprezentację ciągu this z punktu dziesiętnego.

Konwertuje to na double przed obliczeniem reprezentacji ciągu.

  • Jeśli wartość bezwzględna this jest większa lub równa 10 ^ 21, to metody te zwracają wykładniczą reprezentację obliczoną przez this.toStringAsExponential () .

Przykłady:

1000000000000000000000.toStringAsExponential(3); // 1.000e+21
  • W przeciwnym razie wynikiem jest najbliższa reprezentacja ciągu z dokładnie cyframi fractionDigits po przecinku. Jeśli fractionDigits jest równe 0, to kropka dziesiętna jest pomijana.

Parametr fractionDigits musi być liczbą całkowitą spełniającą: 0 <= fractionDigits <= 20.

Przykłady:

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
Greg Lowe
źródło
Musi być zaakceptowanym + Odniesienie + Wyjaśnienie + Przykład
Kohls
1
Twierdzę, że toStringAsFixed () jest metodą zaokrąglania, której należy użyć ze względu na jej niespójność. Na przykład spróbuj5.550.toStringAsFixed(1)
brendan
Uważaj również podczas zaokrąglania do 0 miejsc, ponieważ w tym jednym przypadku wyrażenie zwraca a intzamiast a double, np. num.parse(50.123.toStringAsFixed(0)) is int- można to naprawić, dodając .toDouble()na jego końcu.
abulka
67

num.toStringAsFixed()rundy. Ten zamienia num (n) w ciąg z żądaną liczbą miejsc po przecinku (2), a następnie analizuje go z powrotem do twojego num w jednej słodkiej linii kodu:

n = num.parse(n.toStringAsFixed(2));
Yngvar Natland
źródło
7
To najszybszy sposób na zrobienie tego. Ale to głupie, że dart nie ma bezpośredniego sposobu, aby to zrobić
ThinkDigital,
1
Metoda przedłużenia: extension NumberRounding on num { num toPrecision(int precision) { return num.parse((this).toStringAsFixed(precision)); } }
Vit Veres
31

Powyższe rozwiązania nie zaokrągla odpowiednio liczb. Używam:

double dp(double val, int places){ 
   double mod = pow(10.0, places); 
   return ((val * mod).round().toDouble() / mod); 
}
andyw
źródło
Potwierdzone, zaokrągla się to dp(5.550, 1)poprawnie do 5.6- w przeciwieństwie do najpopularniejszej odpowiedzi, która daje nieco niepoprawną odpowiedź, 5.5jak wskazał @brendan.
abulka
Nie działa dla dp (73.4750, 2) Zwraca 73,47 zamiast 73,48 calculatoroup.com/calculators/math/ ... sprawdź ten link
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");
}

Wydruki: 1.23

Robert
źródło
1
To najlepszy obecnie sposób na zrobienie tego. Zaokrąglenie do dokładności takiej jak 0,01, która sama w sobie nie jest wartością podwójną, nie jest trywialne. Wynik może w ogóle nie być reprezentowalny jako podwójny. Zdecydowanie zalecam używanie liczb całkowitych do wszystkiego, gdzie ważna jest dokładność dziesiętna (np. Pieniądze).
lrn
1
Warto również zauważyć, że jeśli kompilujesz do js, ​​liczby całkowite w Dart również zaczną tracić precyzję i będziesz musiał użyć pakietu takiego jak: pub.dartlang.org/packages/bignum
Greg Lowe
Wydaje się, że ta metoda jest obecnie najlepszym i najbardziej eleganckim sposobem na zrobienie tego.
Giovanni
double nie może być przypisany do int, błąd występuje w linii 3
Gayan Pathirage
13

Aby zaokrąglić podwójną w Dart do określonego stopnia dokładności PO przecinku, możesz użyć wbudowanego rozwiązania w toStringAsFixed()metodzie rzutki , ale musisz przekonwertować to z powrotem na podwójne

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
}

Sultanmyrza Kasymbekov
źródło
11

Zdefiniuj rozszerzenie:

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

Stosowanie:

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
}
CopsOnRoad
źródło
10

Zmodyfikowana odpowiedź @andyw przy użyciu metod Dart Extension:

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

Stosowanie:

var latitude = 1.123456;
var latitudeWithFixedPrecision = latitude.toPrecision(3); // Outputs: 1.123
kubastick
źródło
8

Możesz użyć toStringAsFixed, aby wyświetlić ograniczone cyfry po przecinku. toStringAsFixedzwraca reprezentację ciągu w postaci punktu dziesiętnego. toStringAsFixedakceptuje argument o nazwie, fraction Digitsktóry określa, ile cyfr po przecinku chcemy wyświetlić. Oto jak z niego korzystać.

double pi = 3.1415926;
const val = pi.toStringAsFixed(2); // 3.14
Hadi Mir
źródło
4

Zastosowałem toStringAsFixed()metodę, aby zaokrąglić liczbę do określonych liczb po przecinku EX:

double num = 22.48132906

a kiedy zaokrągliłem to do dwóch liczb w ten sposób:

print(num.toStringAsFixed(2)) ;

Wydrukowano 22.48

a kiedy zaokrągliłem do jednej liczby, zostało wydrukowane 22.5

Sana'a Al-ahdal
źródło
2

Powyższe rozwiązania nie sprawdzają się we wszystkich przypadkach. To, co zadziałało w moim problemie, to takie rozwiązanie, które zaokrągli twoją liczbę (0,5 do 1 lub 0,49 do 0) i pozostawi bez żadnych miejsc po przecinku :

Wejście: 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);

Wyjście: 13

Ten link ma również inne rozwiązania

Runsis
źródło
0

Jeśli nie chcesz żadnych miejsc dziesiętnych, gdy wynikowe liczby dziesiętne są zerami, zadziała coś takiego:

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

Spowoduje to po prostu wyświetlenie 9zamiast, 9.00jeśli dane wejściowe to 9.004i chcesz, aby były to 2 miejsca po przecinku.

Magnus W
źródło
-5

Działa to całkiem nieźle

var price=99.012334554
price = price.roundTodouble();
print(price); // 99.01
Andrew Kawalya
źródło