Dlaczego 0,1 + 0,2 = = 0,3 W D?
assert(0.1 + 0.2 != 0.3); // shall be true
Jest moim ulubionym sprawdzeniem, czy język używa natywnej arytmetyki zmiennoprzecinkowej.
C++
#include <cstdio>
int main()
{
printf("%d\n", (0.1 + 0.2 != 0.3));
return 0;
}
Wyjście:
1
Python
print(0.1 + 0.2 != 0.3)
Wyjście:
True
Inne przykłady
Dlaczego to nie jest prawda dla D? Jak zrozumieć D używa natywnych liczb zmiennoprzecinkowych. Czy to robak? Czy używają jakiejś konkretnej reprezentacji liczb? Coś jeszcze? Dość mylące.
D
import std.stdio;
void main()
{
writeln(0.1 + 0.2 != 0.3);
}
Wyjście:
false
UPDATE
Dzięki LukeH. Jest to efekt zmiennoprzecinkowego stałego fałdowania opisanego tam .
Kod:
import std.stdio;
void main()
{
writeln(0.1 + 0.2 != 0.3); // constant folding is done in real precision
auto a = 0.1;
auto b = 0.2;
writeln(a + b != 0.3); // standard calculation in double precision
}
Wyjście:
false
true
3 answers
Prawdopodobnie zostanie zoptymalizowany do (0.3 != 0.3). Co jest oczywiście fałszywe. Sprawdź ustawienia optymalizacji, upewnij się, że są wyłączone i spróbuj ponownie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-29 14:26:49
(odpowiedź Flynna jest prawidłowa. Ten rozwiązuje problem bardziej ogólnie.)
Wydaje ci się, że zakładasz, OP, że nieścisłość zmiennoprzecinkowa w Twoim kodzie jest deterministyczna i przewidywalnie błędna (w pewnym sensie Twoje podejście jest biegunowym przeciwieństwem podejścia ludzi, którzy jeszcze nie rozumieją zmiennoprzecinkowej).
Chociaż (jak wskazuje Ben) nieścisłość zmiennoprzecinkowa jest deterministyczna, z punktu widzenia twojego kodu, jeśli nie będąc zbyt rozmyślnym o tym, co dzieje się z Twoimi wartościami na każdym kroku, nie będzie to miało miejsca. Dowolna liczba czynników może prowadzić do sukcesu 0.1 + 0.2 == 0.3
, optymalizacja czasu kompilacji jest jedną, poprawione wartości dla tych liter są inne.
Polegaj tutaj ani na sukcesie, ani na porażce; nie polegaj na równości zmiennoprzecinkowej tak czy inaczej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-01 15:13:10
Zgodnie z moją interpretacją specyfikacji języka D, arytmetyka zmiennoprzecinkowa na x86 używałaby wewnętrznie 80 bitów precyzji, zamiast tylko 64 bitów.
Trzeba by jednak sprawdzić, czy to wystarczy, aby wyjaśnić wynik, który obserwujesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-29 14:14:44