zagadka dla programistów R

Odpowiedz Nowy wątek
2014-12-14 22:25
0

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

edytowany 6x, ostatnio: Laflx, 2014-12-14 22:29

Pozostało 580 znaków

2014-12-14 22:41
1

Czemu tylko R?
W c# to będzie np 0.4

nie wiedziałem, że w innych językach też się tak dzieje... a umiesz to wyjasnić ? - Laflx 2014-12-14 22:42
Cecha i mantysa, poczytaj o tym jak reprezentowane są liczby w komputerze. - dam1an 2014-12-14 22:46

Pozostało 580 znaków

2014-12-14 22:48
5

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

http://ideone.com/QNMNwG


"(...) otherwise, the behavior is undefined".
edytowany 7x, ostatnio: Endrju, 2014-12-15 00:04
Wyłącz optymalizator ;) Bo pewnie ci to 0.1+0.1 w trakcie kompilacji wylicza i robi z tego 0.2 ;] - Shalom 2014-12-14 23:23
Wszystko wpisuje z konsoli bez optymalizacji. :-/ - Endrju 2014-12-14 23:24
A zobacz co ci generuje gcc -S na tym twoim testowym kodzie, obstawiam że nie ma tam tych 0.1 - Shalom 2014-12-14 23:31
Takie coś mam: http://ideone.com/Ha7AEG W ASM jest tak jak powinno, najpierw jedno dodawanie, potem drugie. Trochę mnie dziwi, że 0.1 + 0.4 to dokładnie 0.5. - Endrju 2014-12-14 23:37

Pozostało 580 znaków

2014-12-14 22:56
10

Uwielbiam jak ludzie śpią na metodach numerycznych a potem się chwalą takimi odkryciami :D 0.1 to okresowy ułamek binarny.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
edytowany 1x, ostatnio: Shalom, 2014-12-14 22:57
hehe, a już myślałem, że odkryłem Amerykę... (Nie studiowałem informatyki.) - Laflx 2014-12-14 23:09
Ja spałem, bo były nudne. A reprezentacja liczb to raczej podstawy programowania niż MN. - somekind 2014-12-14 23:37
@somekind takie czasy że dzisiaj listy jednokierunkowe omawia się na jakimś 3 semestrze ASD albo innych "zaawansowanych strukturach danych", więc pewnie reprezentacja liczb też już tylko na metodach numerycznych ;) - Shalom 2014-12-14 23:39
Ja to miałem na matematyce dyskretnej chyba. - dam1an 2014-12-14 23:40
a propoS tematów czy studia są potrzebne. To jest idealny przykład, że czasem się przydają ;) - Sarrus 2014-12-16 14:19

Pozostało 580 znaków

2014-12-14 23:56
3

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.


edytowany 1x, ostatnio: furious programming, 2014-12-14 23:57
Pokaż pozostałe 12 komentarzy
Dzięki, wiecznie zapominam jak się to pisze... :) - furious programming 2014-12-16 13:25
Never go full furious. Just never :D - EroSanin 2014-12-16 13:27
jak to się nie da, wszystko się da. W R można zrobić wszystko. Jest to język intepretowalny i wektorowy , więc bijen a głowę wszystkie Javy, C, D, E, F, G... i jakie hejtowanie mi imputujesz? uspokuj się furious - Laflx 2014-12-16 13:33
@Laflx R jest bardziej językiem skryptowym (potrzebuje interpretera) więc ciężko z niego zrobić coś więcej niż skrypt. Poczytaj o różnicach między językami interpretowanymi a kompilowanymi ;) - EroSanin 2014-12-16 13:39
Panu @Laflx już dziękujemy - odpocznij sobie i nabierz pokory; - furious programming 2014-12-16 13:40

Pozostało 580 znaków

2014-12-15 16:04
0

ta zagadka jest trudna dla mnie ale mam inna :) z matmy :)

y'-x=0

ile wynosi y ? :)

Pokaż pozostałe 4 komentarze
No ale czemu niby zwykle równanie różniczkowe ma być zagadka? o_O - Shalom 2014-12-15 17:10
a czemu nie ? - krzychu82a 2014-12-15 17:16
Jestem tylko zwykłym licealistą, nie wiem jak ugryźć to drugie :( - mad_penguin 2014-12-15 17:56

Pozostało 580 znaków

2014-12-15 16:35
0

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? :/

To jest zupełnie nielogiczne, tylko ja odnoszę takie wrażenie? Tak. - dam1an 2014-12-15 16:47
A teraz przeczytaj jak reprezentuje się liczby zmiennoprzecinkowe w komputerze... - Shalom 2014-12-15 16:52

Pozostało 580 znaków

2014-12-15 16:50
0

Arytmetyka zmiennoprzecinkowa w IEEE 754 nie działa tak jak matematyka, po prostu.

Poczytaj: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems


"(...) otherwise, the behavior is undefined".

Pozostało 580 znaków

2014-12-15 17:10
0

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.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2014-12-15 17:17
0

Tam nie ma żadnych zaokrągleń, po prostu ludzie używają niedoskonałego systemu do obliczeń. ;)


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
Owszem, są zaokrąglenia, np. jak 64-bitową zmienną typu double przepisujesz z 80-bitowego rejestru do 64-bitów pamięci. Intele wewnętrznie liczą na 80 bitach. To prowadzi do znacznie ciekawszych zagadek, np. if (x == 1.0) cout &lt;&lt; &quot;true &quot; else cout &lt;&lt; &quot;false &quot;; powtórzone dwa razy pod rząd wypisuje false true. - Krolik 2014-12-16 14:45

Pozostało 580 znaków

2014-12-15 17:27
0

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

edytowany 1x, ostatnio: krzychu82a, 2014-12-15 17:28

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0