Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Blad przy odejmowaniu liczby typu FLOAT
cagrET
post 1.11.2005, 19:43:16
Post #1





Grupa: Zarejestrowani
Postów: 90
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Opole

Ostrzeżenie: (0%)
-----


Skrypt:
<?php echo 12.00 - 11.99; ?>

na linuxie wersja php 4.4.10 (sprawdzone na dwoch serwarach) wynik: 0.0099999999999998
na windowsie wersja php 4.3.9 wynik: 0.01

Ktos mial juz taki problem? I to jest duzy problem, bo blad ten pojawia sie w serwisie ecommerce, gdzie takie obliczenia sa istotne.

Na razie jedyne rozwiazanie jakie widze to wszedzie z obliczeniami gdzie wystepuje odejmowanie dodawac round:

<?php echo round(12.00 - 11.99, 2); ?>


--------------------
code.gosu.pl
Go to the top of the page
+Quote Post
s_w_ir
post 1.11.2005, 21:55:03
Post #2





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


Może okaże sie że sie myle, ale uczyłeś się architektury komputerów? Liczby ułamkowe zapisywane w systemach dwójkowych są przeważnie przybliżeniem liczby którą chce sie zapisać. Jest to wynikiem ograniczonych mozliwości systemu dwójkowego np. liczba 0.3 ma w systemi dwójkowym rozwinięcie okresowe. Jeśli zapiszemy ją na 8 bitach tom po ponowym przekonwertowaniu jej na system dziesiętny otrzymamy 0,296875 czyli bląd na 1,05%( przykład zaczerpnięty z książki).
Jednak co jest śmieszne jeśli dodasz spowrotem to co odjołęś wynik będzie dobry smile.gif tzn = 12
  1. <?php
  2. $b=12.00 - 11.99;
  3. $b+=11.99;
  4. echo $b;
  5. ?>
Go to the top of the page
+Quote Post
cagrET
post 1.11.2005, 21:57:21
Post #3





Grupa: Zarejestrowani
Postów: 90
Pomógł: 0
Dołączył: 3.04.2003
Skąd: Opole

Ostrzeżenie: (0%)
-----


Juz mi paru linuxowcow dalo wyklad na temat cech i mantys. Ale oni nic nie rozumieja, ze po odjeciu 11.99 od 12.00 powinno byc 0.01. Bill Gates power O_o


--------------------
code.gosu.pl
Go to the top of the page
+Quote Post
s_w_ir
post 1.11.2005, 22:06:16
Post #4





Grupa: Zarejestrowani
Postów: 315
Pomógł: 1
Dołączył: 6.08.2003
Skąd: Kielce

Ostrzeżenie: (0%)
-----


No powinno i nic nie poradzisz chyba że masz jakąs opcje żeby liczby kodować systemem dwójkowo-dziesiętnym- najbardziej dokładny do liczb zmienno przecinkowych ale też chyba bardziej pamięcio żerny- wymaga więcej bajtów na liczbe. Żeby sie za bardzo nie motać użyj ceil() lub round()
Go to the top of the page
+Quote Post
ghostrider
post 2.11.2005, 10:16:40
Post #5





Grupa: Zarejestrowani
Postów: 135
Pomógł: 0
Dołączył: 30.09.2005
Skąd: k-rk

Ostrzeżenie: (0%)
-----


albo mozna pracowac na liczbach calkowitych i dopiero na samym koncu zamieniac na zmiennoprzecinkowe

  1. <?php
  2. $a = 12.00 * 100;
  3. $b = 11.99 * 100;
  4.  
  5. $c =( $a - $b)/100;
  6.  
  7. print $c; /* i git */
  8. ?>


--------------------
There are 10 types of people in the world:
-Those who understand binary, and those who don't...
There's no place like 127.0.0.1
Go to the top of the page
+Quote Post
mike
post 2.11.2005, 10:27:09
Post #6





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

Ostrzeżenie: (0%)
-----


php zawsze było kiepskie w te klocki.
Skorzystaj z BCMath(arytmetyka liczb dużej precyzji)
  1. <?php
  2.  
  3. echo bcsub( 12.00, 11.99, 2 );
  4.  
  5. ?>
Go to the top of the page
+Quote Post
sobstel
post 2.11.2005, 10:43:44
Post #7





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

Ostrzeżenie: (0%)
-----


ja tylko dodam ze problem ten oczywiscie dotyczy zarowno linuxa jak i windowsa. (btw - nie na temat - mysqla tez dlatego tam gdzie mozna i tam gdzie bedziemy stosowac porownania itp. to lepiej stosowac DECIMAL niz FLOAT)


--------------------
"If debugging is the process of removing bugs, then programming must be the process of putting them in..."
sobstel.org
Go to the top of the page
+Quote Post
dr_bonzo
post 2.11.2005, 10:47:52
Post #8





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat(ghostrider @ 2005-11-02 10:16:40)
albo mozna pracowac na liczbach calkowitych i dopiero na samym koncu zamieniac na zmiennoprzecinkowe

  1. <?php
  2. $a = 12.00 * 100;
  3. $b = 11.99 * 100;
  4.  
  5. $c =( $a - $b)/100;
  6.  
  7. print $c; /* i git */
  8. ?>

Jest tylko male ale, juz tutaj "tracisz precyzje":
$b = 11.99 * 100;

biggrin.gif

Ale gdy potrzebujesz jedynie 2 cyfr po przecinku -- wystarczy int, a na koniec podziel przez 100.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
hwao
post 2.11.2005, 17:42:03
Post #9


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




juz byl taki temat, o ile dobrze pamietam.

I to nie byla wina php z tego co pamietam to Seth pokazywal to samo w innych jezykach.

To wina komputera
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 25.07.2025 - 08:07