Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: dziwne działanie round()
Forum PHP.pl > Forum > PHP
vi-valdi
Czy ktoś wie dlaczego tak się dzieje.
Uruchamiam dwa prawie identyczne kody"

Kod 1

[php:1:25440baf64]<?php
$cena = 9.1*0.75; // = 6.825
$cena_z = round ($cena, 2);
print ("<p>$cena_z</p>");
print ("<p>" .gettype($cena). "</p>");
print ("<p>" .gettype($cena_z). "</p>");
?>[/php:1:25440baf64]

Kod 2

[php:1:25440baf64]<?php
$cena = 6.825;
$cena_z = round ($cena, 2);
print ("<p>$cena_z</p>");
print ("<p>" .gettype($cena). "</p>");
print ("<p>" .gettype($cena_z). "</p>");
?>[/php:1:25440baf64]

Zmienna $cena_z jest zaokrąglana do dwóch miejsc po przecinku.
Zmienne $cena i $cena_z sprawdzam gettype() aby mieć pewność, że są double.

A teraz przedstawiam wynik działania powyższych kodów

Kod 1

Kod
6.82

double

double


Kod 2

Kod
6.83

double

double


? dlaczego Kod 1 daje wynik 6.82, a Kod 2 daje wynik 6.83.
Wydaje mi się, że wyniki powinny być identyczne.
A może robię gdzieś jakiś błąd.
-
scanner
[php:1:f9be7e1d43]<?php
$cena = 9.1*0.75; // = 6.825
var_dump($cena); // float(6.825)
?>[/php:1:f9be7e1d43]float, nie double - zatem round może inaczej zaokrąglić moim zdaniem.
vi-valdi
Dzięki scanner, naprowadziłeś mnie tym float
Cała sprawa leży w precyzji liczb zmiennoprzecinkowych.

EX z manuala

Cytat
floor((0.1+0.7)*10) zwykle ma wartość 7, zamiast oczekiwanej 8, gdyż wewnętrzna reprezentacja tego wartości to liczba 7.9999999999....


Widocznie 9.1 * 0.75 = 6.825 jest reprezentowane przez 6.8249999999...
i round ($cena, 2) zaokrągla wg 0.004 w dół.

Żeby mieć dokładny wynik trzeba zastosować: arytmetyke liczb dużej precyzji.

[php:1:34b6477e4e]<?php
$cena = bcmul ( 9.10, 0.75, 3);
?>[/php:1:34b6477e4e]
---

załatwia sprawę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.