2013-03-20 10 views
5

Mam dziwny problem podczas korzystania Math.floor funkcję wartości podwójnych zwiększonymi o 0,1 każdym razem.LUA (Corona SDK) Math.floor() zwraca błędną wartość z przyrostem 0,1

Zdarza się tylko z przyrostem 0,1 i zaczynają się wartość 5

Exemple: Math.floor (4) powróci ale Math.floor (5) zwracają !!!

Można spróbować samemu, z tego prostego kawałek kodu:

for i=3,7,0.1 do 
    print("val : "..i.." floor : "..math.floor(i)) 
end 

Oto wynik powyższego kodu:

Corona Simulator[1494:707] val : 3 floor : 3 
Corona Simulator[1494:707] val : 3.1 floor : 3 
Corona Simulator[1494:707] val : 3.2 floor : 3 
Corona Simulator[1494:707] val : 3.3 floor : 3 
Corona Simulator[1494:707] val : 3.4 floor : 3 
Corona Simulator[1494:707] val : 3.5 floor : 3 
Corona Simulator[1494:707] val : 3.6 floor : 3 
Corona Simulator[1494:707] val : 3.7 floor : 3 
Corona Simulator[1494:707] val : 3.8 floor : 3 
Corona Simulator[1494:707] val : 3.9 floor : 3 
Corona Simulator[1494:707] val : 4 floor : 4 
Corona Simulator[1494:707] val : 4.1 floor : 4 
Corona Simulator[1494:707] val : 4.2 floor : 4 
Corona Simulator[1494:707] val : 4.3 floor : 4 
Corona Simulator[1494:707] val : 4.4 floor : 4 
Corona Simulator[1494:707] val : 4.5 floor : 4 
Corona Simulator[1494:707] val : 4.6 floor : 4 
Corona Simulator[1494:707] val : 4.7 floor : 4 
Corona Simulator[1494:707] val : 4.8 floor : 4 
Corona Simulator[1494:707] val : 4.9 floor : 4 
Corona Simulator[1494:707] val : 5 floor : 4 
Corona Simulator[1494:707] val : 5.1 floor : 5 
Corona Simulator[1494:707] val : 5.2 floor : 5 
Corona Simulator[1494:707] val : 5.3 floor : 5 
Corona Simulator[1494:707] val : 5.4 floor : 5 
Corona Simulator[1494:707] val : 5.5 floor : 5 
Corona Simulator[1494:707] val : 5.6 floor : 5 
Corona Simulator[1494:707] val : 5.7 floor : 5 
Corona Simulator[1494:707] val : 5.8 floor : 5 
Corona Simulator[1494:707] val : 5.9 floor : 5 
Corona Simulator[1494:707] val : 6 floor : 5 
Corona Simulator[1494:707] val : 6.1 floor : 6 
Corona Simulator[1494:707] val : 6.2 floor : 6 
Corona Simulator[1494:707] val : 6.3 floor : 6 
Corona Simulator[1494:707] val : 6.4 floor : 6 
Corona Simulator[1494:707] val : 6.5 floor : 6 
Corona Simulator[1494:707] val : 6.6 floor : 6 
Corona Simulator[1494:707] val : 6.7 floor : 6 
Corona Simulator[1494:707] val : 6.8 floor : 6 
Corona Simulator[1494:707] val : 6.9 floor : 6 
Corona Simulator[1494:707] val : 7 floor : 6 

Jeśli to może pomóc, gdybyśmy zastosowali modulo 1 na wyniku wartości błędu, otrzymujemy to jako wynik: 0.99999999999999

+0

możliwe duplikat [? Dlaczego Lua arytmetyka nie jest równe sobie] (http://stackoverflow.com/questions/6366954/why-is-lua-arithmetic-is-not-equal-to-itself) – finnw

Odpowiedz

4

rzeczywiście jest to powszechny problem float,

Oto oficjalna odpowiedź Dostałem od wsparcia koronowym:

Witam,

Co widzisz to ogólna problem z liczbami zmiennoprzecinkowymi. Wszystkie liczby w języku Lua są liczbami zmiennoprzecinkowymi i jako takie podlegają za błędy zaokrąglania. Dodanie 0,1 do innego numeru zmiennoprzecinkowego nie jest dokładnie , a błąd kumuluje się, gdy jest używany wielokrotnie. Jeśli sądzisz, że liczba wynosi 5.0, może to być 4,99999999999999999, czyli podłoga zwraca 4. Instrukcja drukowania może zaokrąglić w górę przed wydrukiem .

Biblioteka matematyczna jest standardowym kodem Lua (v5.1) i nie została zmodyfikowana dla Corona.

Możesz zgłębiać tematy związane z zaokrąglaniem tematów lub zmiennoprzecinkowych, ale w generatorze należy zachować ostrożność podczas używania matematyki zmiennoprzecinkowej.

Pozdrowienia Tom

- Corona Labs - Wsparcie [email protected]

4

F Numery punktowe są diabelskie. Nie używaj ich jako liczników pętli.

for i = 30, 70 do 
    local i = i/10 
    print("val : "..i.." floor : "..math.floor(i)) 
end 
+0

Dzięki, działa w ten sposób, ale chodzi o to, że nie używam pętli for w moim prawdziwym projekcie. Używam prostego dodatku (aby zaktualizować pozycję postaci). Próbowałem zastąpić każdy zmiennoprzecinkowy w moim kodzie wartościami wyliczonymi (np. 1/10) i nadal nie działa :( – chip

+0

@ user1029976 - Możesz zaokrąglić do najbliższego n/10: 'x = math.floor (x * 10 + 0.5)/10' –

+0

@ user1029976 Podstawowym problemem jest to, że 0.1 (lub 1/10) nie jest skończoną liczbą binarną (to '0.0001100110011 ...'). Reprezentacja zmiennoprzecinkowa musi zakryć to w pewnym momencie, dlatego w pewnym momencie pojawiają się błędy zaokrąglania. Zwiększ zamiast tego swoją pozycję postaci o 1 i dziel ją przez 10 tylko wtedy, gdy faktycznie używasz tej wartości. –