Uderzyło mnie, że w zależności od tego jakiej metody użyjemy w danym języku do zaokrąglania części dziesiętnych dwóch liczb, tj. 2.35
oraz 2.45
, to w większości przypadków otrzymamy... błędne wyniki. Błędne, bo niezgodne z zasadą:
"Jeśli pierwsza (licząc od lewej strony) z odrzuconych cyfr jest równa 5 i nie następuje po niej żadna cyfra inna niż zero, to ostatnią pozostawioną cyfrę powiększa się o jednostkę, jeśli jest to cyfra nieparzysta."
Python:
# Wynik poprawny.
print(np.around(2.35, decimals=1), np.around(2.45, decimals=1))
# Out: 2.4 2.4
# Wynik błędny.
print(round(2.35, 1), round(2.45, 1))
# Out: 2.4 2.5
# Wynik błędny.
print("%.1f" % 2.35, "%.1f" % 2.45)
# Out: 2.4 2.5
Java:
// Wynik błędny.
System.out.println((double) Math.round(2.35 * 10) / 10 + " " + (double) Math.round(2.45 * 10) / 10);
// Out: 2.4 2.5
// Wynik błędny.
System.out.println(String.format("%.1f", 2.35) + " " + String.format("%.1f", 2.45));
// Out: 2,4 2,5
// Wynik błędny.
DecimalFormat df = new DecimalFormat("#.#");
System.out.println(df.format(2.35) + " " + df.format(2.45));
// Out: 2,4 2,5
// Wynik błędny.
public static void main(String[] args) {
System.out.println(round(2.35, 1) + " " + round(2.45, 1));
}
public static double round(double value, int places) {
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
// Out: 2.4 2.5
// Dla innych RoundingMode, np. HALF_EVEN, wynik również błędny.
// Wynik błędny.
import org.apache.commons.math3.util.Precision;
System.out.println(Precision.round(2.35, 1) + " " + Precision.round(2.45, 1));
// Out: 2.4 2.5
W Matlabie, JS'ie i C# nie udało mi się znaleźć metody, która zwracałaby wartości poprawne.
EDIT
Jeszcze taka ciekawostka:
# Python.
In[26]: x = 2.35
In[27]: y = 2.45
In[28]: print("%.20f, %.20f" % (x, y))
Out [28]: 2.35000000000000008882, 2.45000000000000017764
// Java.
System.out.println(String.format("%.20f", 2.35) + " " + String.format("%.20f", 2.45));
// Out: 2,35000000000000000000 2,45000000000000000000