Znajdź liczbę x z przedziału od 0 do 1 dla którego poniższe wyrażenie zwraca wartość FALSE:
x + 0.1 + 0.1 == 0.1 + 0.1 + x
autor: Przemysław Biecek
Znajdź liczbę x z przedziału od 0 do 1 dla którego poniższe wyrażenie zwraca wartość FALSE:
x + 0.1 + 0.1 == 0.1 + 0.1 + x
autor: Przemysław Biecek
Czemu tylko R?
W c# to będzie np 0.4
Działania w IEEE 754 niekoniecznie są łączne. Tzn: (A + B) + C
może być różne od A + (B + C)
. Tzn: kolejność dodawania może mieć znaczenie. Najwidoczniej dla tych liczb tak właśnie jest.
Chociaż jakoś nie udaje mi się tego zreprodukować w C++.
Edit: dla 0.5 już działa:
0.5 + 0.1 + 0.1 = 0.70000004768371582031250000000000
0.1 + 0.1 + 0.5 = 0.69999998807907104492187500000000
Uwielbiam jak ludzie śpią na metodach numerycznych a potem się chwalą takimi odkryciami :D 0.1 to okresowy ułamek binarny.
Znajdź liczbę x z przedziału od 0 do 1 dla którego poniższe wyrażenie zwraca wartość FALSE:
Znaleźć nie problem, wystarczy kilka linii kodu; Gorzej już z wyjaśnieniem dlaczego tak jest :]
uses
{$IFNDEF FPC} Types, {$ENDIF} Math;
var
dblX: Double = 0.0;
begin
while CompareValue(dblX, 1.0) < GreaterThanValue do
begin
WriteLn('x = ', dblX:1:1, ': ', dblX + 0.1 + 0.1 = 0.1 + 0.1 + dblX);
dblX := dblX + 0.1;
end;
ReadLn;
end.
Pod FPC i Delphi7 wyniki takie same, z optymalizacjami i bez:
x = 0.0: TRUE
x = 0.1: TRUE
x = 0.2: TRUE
x = 0.3: TRUE
x = 0.4: TRUE
x = 0.5: FALSE
x = 0.6: FALSE
x = 0.7: FALSE
x = 0.8: FALSE
x = 0.9: TRUE
x = 1.0: TRUE
Co ciekawe, @dam1an podał, że w C# wartość 0.4
da False
- tu jest inaczej.
ta zagadka jest trudna dla mnie ale mam inna :) z matmy :)
y'-x=0
ile wynosi y ? :)
To jest zupełnie nielogiczne, tylko ja odnoszę takie wrażenie? bo:
x + 0.1 + 0.1 = 0.1 + 0.1 + x
x + 0.1 + 0.1 - 0.1 - 0.1 -x = 0
0 = 0 // prawda
Zatem jak kompilator przepuszcza 0.5, 0.6, 0.7, 0.8? :/
Arytmetyka zmiennoprzecinkowa w IEEE 754 nie działa tak jak matematyka, po prostu.
Poczytaj: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Mówiąc prościej: floaty i double to liczby skończonej precyzji, więc arytmetyka na nich wymusza stosowanie zaokrągleń. Różna kolejność zaokrągleń prowadzi do różnych wyników.
Tam nie ma żadnych zaokrągleń, po prostu ludzie używają niedoskonałego systemu do obliczeń. ;)
wg mnie znaczenie ma nie tylko zapisanie tych liczb w pamiec ale i dodawanie tych liczb ale i porownanie
na kazdej operacji jest blad
im wiecej operacji liczbowych tym mniejsza dokladnosc
Świetny przykład na pokazanie komuś, dlaczego do biznesowych zastosowań w javie tylko BigDecimal.
Pewnie kiedyś wkleję w gitlabie.
ja za bardzo nie kumam tych systemow cyfrowych ale podobno lepiej sie mnozy niz sumuje chyba sume sie wykonuje iloczynowo jakos
przesuwajac bity w ramce mozemy realizowac mnozenie lub dzielenie przez 2
00000001 - 1
00000010 - 2
00000100 - 4
00001000 - 8
00010000 - 16
Cóż... to zadanie w połączeniu ze stwierdzeniem, że "już wszyscy analitycy klepią w R" utiwerdziło mnie w przekonaniu, że jednak Java ma przed sobą świetlaną przyszłość...
Ten R to w ogóle opłacalny język programowania? Czy taki typowy dla Januszów;) http://www.r-project.org/ Nie ma dobrego kursu, tu chyba pani Lidia z urzędu by się nie połapała.
Ja używam czasem R do raportów (Sweave FTW).
Co do opłacalności to R razem ze Swiftem są "odkryciami" 2014 roku.
ten R przypomina troche matlaba
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.