ugrás a tartalomhoz

php round probléma

mdesign · 2008. Júl. 10. (Cs), 09.22
Sziasztok!

Van egy ilyen kódom:

<?php

echo '1200000 ->'.round(1200000, 2);

?>
Aminek ez lesz a végeredménye:
1200000 ->1.2E+6
Tud valaki segíteni, hogy ezt hogy lehetne elkerülni?

Üdv Karesz
 
1

php manual

gex · 2008. Júl. 10. (Cs), 09.35
http://hu2.php.net/manual/en/function.round.php#82436

kommentek között nem találtál megoldást?
2

kommentek

mdesign · 2008. Júl. 10. (Cs), 09.46
olvastam a kommenteket.. láttam, hogy valaki ugyanígy felveti ezt a kérdést, de választ nem találtam rá, csak azt, hogy hogyan írjunk saját round fv-t.

Azért kérdeztem meg itt fórumon,mert gondoltam van valami szebb módja is mint megírni újra amit elvileg már tartalmaz a php.
3

rosszul működik a round

gex · 2008. Júl. 10. (Cs), 10.13
beleolvasgatva a kommentekbe úgy néz ki, hogy a round függvény bizonyos esetekben elég rosszul működik.

a printf vagy sprintf függvény nem segít neked? mindekttő ugyanazt csinálja, csak az egyik kiírja a másik meg visszaadja a formázott szöveget.
4

Segítség

tolmi · 2008. Júl. 10. (Cs), 11.39
Elkerülni mondjuk így lehet relatíve gyorsan:

$rounded = round(1200000, 2);
$data = sprintf("%0.2f", $rounded);
echo "1200000 -> ".$data;
Olyan butaságot meg ne állítsunk hogy a round néha rosszul működik. Nagyon is jól működik. Az a notáció, vagy jelöléstan az exponenciális forma, vagy anglisül scientific notation. A lebegőpontos számok gépi tárolásának mikéntjét ha valaki ismeri (ha meg nem, akkor menjen és tanulja meg vagy hagyjon fel a szakmával), akkor ezen nem lepődik meg.

Az sprintfről egyébként tényleg nem sokan tudják, hogy a %f tud ilyet, a %e meg scientific formázást. Mostmár tudjátok ;)
5

olvasd a manual kommentjeit

gex · 2008. Júl. 10. (Cs), 11.54
olyan butaságot meg ne állítsunk, hogy butaságot állít az, aki azt mondja hogy a round néha rosszul működik. ;)

  1. http://hu2.php.net/manual/en/function.round.php#81465
    If you tray to round 2.135 to second digit, expexted value is "2.14", but returned value is "2.13" : WRONG!!!

  2. http://hu2.php.net/manual/en/function.round.php#82436
    echo round(1100000); // 1100000
    echo round(1200000); // 1.2E+6
    echo round(1300000); // 1300000
    echo round(1400000); // 1.4E+6


nem a tudományos jelöléssel (ez talán egy populárisabb elnevezés) van a baj, hanem azzal, hogy a php nem következetes.
a manuálban meg szépen le van írva sprintf címszó alatt az összes típus módosító (vagy mi). a %f és %e is.

én azért személy szerint köszönöm az okítást. :P
6

round?

Őry Máté · 2008. Júl. 10. (Cs), 12.15
If you tray to round 2.135 to second digit, expexted value is "2.14", but returned value is "2.13" : WRONG!!!


Mivel a számítógép nem tízes számrendszerben „gondolkodik”, a lebegőpontos számoknál sem.

Az meg nem a round gondja, hogy az egész számból hogyan csinál a php sztringet.
7

Jól beszélsz

tolmi · 2008. Júl. 10. (Cs), 12.34
...viszont a második példában szereplő inkonzisztencia ha nem is hiba, de hanyagságnak hanyagság. Valamint tényleg nem a round hibája, ezt el kell fogadnunk.

Tartom a véleményem, hogy a PHP round függvénye kiválóan és hibátlanul müködik.

Ui.: Nem akartam ám erőszakoskodni a stílusommal, ezért bocsánat.
10

azert valami van...

toro · 2008. Júl. 10. (Cs), 13.00
lehet, hogy inkozisztencia, de azert zavaro:
1000*round(.2135, 3) // 214
100*round(2.135, 2)  // 213
10*round(21.35, 1)   // 214
round(213.5)         // 214
12

Tud valaki jobbat?

tolmi · 2008. Júl. 10. (Cs), 13.21
Tud valaki olyan nyelvet, amelyben ez a viselkedés nem jelentkezik?

Nekem most csak C és PHP áll rendelkezésemre, ha senki nem jelentkezik, akkor később majd kipróbálom magam. Bár meglepne ha lenne olyan pályázó, aki másként viselkedne.
14

Kettő

Őry Máté · 2008. Júl. 10. (Cs), 13.39
2 melyik hatványa osztható szerinted tízzel?
17

nálam 2.14

gex · 2008. Júl. 10. (Cs), 14.11
kipróbáltam én is ezt az ominózus esetet:
echo round(2.135, 2); // 2.14

nálad pedig 2.13.

szerk: php5.2.3, te milyen verzión próbálod?
19

Milyen platform?

Őry Máté · 2008. Júl. 10. (Cs), 14.31
$ php -a
Interactive shell

php > echo round(2.135, 2);
2.13

$ php -v
PHP 5.2.4-2ubuntu5.2 with Suhosin-Patch 0.9.6.2 (cli) (built: Jul  3 2008 16:46:01) 
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
20

debian linux

gex · 2008. Júl. 10. (Cs), 14.43

php > echo round(2.135, 2);
2.14

PHP 5.2.3-0.dotdeb.0 with Suhosin-Patch 0.9.6.2 (cli) (built: Jun  4 2007 11:34:30)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
24

Nálam is változó

Török Gábor · 2008. Júl. 10. (Cs), 15.15
Egyik gép itt /PHP 5.1.6 (cli) (built: Sep 20 2007 10:16:10)/:
round(2.135, 2) // 2.14
Másik gép itt /PHP 5.2.6 (cli) (built: May 8 2008 10:23:54)/:
round(2.135, 2) // 2.13
Részlet az Emacs dokumentációjából:
Rounding a value equidistant between two integers may choose the integer closer to zero, or it may prefer an even integer, depending on your machine. For example, (round 2.5) can return 3 on some systems, but 2 on others.
21

nalam 5.2.3

toro · 2008. Júl. 10. (Cs), 14.49
nalam is 5.2.3 a PHP

Biztos az aramingadozas a hibas :)
22

off

gex · 2008. Júl. 10. (Cs), 14.52
műveletek törtszámokkal:
10db...1000ft
20db...1800ft
50db...4000ft
gyors, PONTOS, megbízható!

:D
23

ha mar off

toro · 2008. Júl. 10. (Cs), 15.01
ha mar off

ezt a round fuggvenyt hasznaljak a kozertben is, hiszen arban 10 x 1 kifli != 10 kifli :)
25

érdekesség: banker's rounding

gex · 2008. Júl. 10. (Cs), 15.23
keresgéltem, hogy vannak-e hasonlóan problémás számok, és találtam egy ilyet:
http://bugs.php.net/bug.php?id=24142#c64238 (wikipedia leírás)

a manual egy kommentjéből viszont úgy tűnik, hogy nincs már ilyenfajta kerekítés a php-ban. a kommentben lévő linket követve találtam egy cikket a kerekítés fajtáiról (vizualizálva is), ami eléggé meglepett, mert nem tudtam, hogy ennyiféleképpen lehet kerekíteni. a közgázosok gondolom itt előnyben lehetnek.

elképzelhető, hogy round függvényen belül valamilyen kacifántos kerekítés van? pl ez megmagyarázná, hogy miért más a két eredmény. :)
16

echo, print

Őry Máté · 2008. Júl. 10. (Cs), 13.52
Azért echoval, printtel közvetlenül lebegőpontos számot kiírni szerintem szép felhasználói felületen annyira nem kellene. Már csak a tizedespont miatt is. (Pl a printf locale-specifikusan kezeli.)
8

nem értem

gex · 2008. Júl. 10. (Cs), 12.36
nem értem, hogy mit akarsz mondani a tízes számrendszerrel. ha nem 10-es számrendszerben gondolkozna, akkor nem lenne round, ceil, floor függvény, hiszen nem tudná értelmezni, hogy az 1000 az ezret, nyolcat, hatvannégyet vagy ezret jelent. ráadásul a tudományos jelölésnél az E utáni rész a 10 hatványát jelöli, pl a 1.2E+6 az 1.2*10^6, azaz 1200000. mi ez, ha nem tízes számrendszer?

és nem értem az "egész szám" és "sztring" szavakat sem. az idézetben valószínűleg nem a sztring jelölés miatt van idézőjel.
13

Nézz utána

tolmi · 2008. Júl. 10. (Cs), 13.23
Tényleg nézz utána a lebegőpontos számok tárolásának hardveresen, meg úgy egyáltalán a számábrázolásnak binárisan. Amíg ezt nem tudtad le, addig nem igazán tudjuk folytatni az okfejtést veled.

Ha meg ismered, akkor pedig egyáltalán nem értem hogy miért írtad le azt amit írtál...vagy hogy mit akartál kommunikálni.
18

lehet hogy régen volt

gex · 2008. Júl. 10. (Cs), 14.15
elképzelhető, hogy már régen tanultam ezeket és elfelejtettem ezt-azt, de ez 3 tizedesjegy még nem fogja összezavarni a lebegőpontos számábrázolást annyira, hogy pontatlan legyen. vagy ha igen akkor én kérek elnézést.

viszont látom te hozzáértő vagy, ezt meg tudod nekem - laikusnak - magyarázni?
26

A C round

tolmi · 2008. Júl. 10. (Cs), 16.04
[Kitöröltem az előzőt, bocsi, hülyeség volt]

Mivel feltételezem a C beépített round-ját használja, ezért libc implementációtól kezdve a hardverig sokminden lehet az oka.
9

binaris problema?

toro · 2008. Júl. 10. (Cs), 12.52
nezetem szerint a szamitogepek belso szamabrazolasara nem kellene hivatkozni, hiszen azok elott, akik a matematikai fuggvenyeket letrehozzak ez ismert problema kell legyen, hiszen hasonlo furcsasagokat maz az os zsebszamolo gepek is krealtak.

jo ha ismert a gond azok elott akik a fuggveny hasznalni akarjak, es feltetelezem, hogy a szamos beiras (es felteszem ugyanannyi bugreport) hatasara a feljesztok nagy gondodssaggal at fogjak az egeszet turni
11

Ez már szakállas

tolmi · 2008. Júl. 10. (Cs), 13.20
Elég régi a sztori, nem is szeretném tovább feszegetni, mert lassan hitvallásba fordul át a dolog. A UNIX és egyáltalán a C így kezeli a dolgot több tíz éve, nekem ez az etalon. Elfogadom, használom, nem furcsálkodok.

A lényeg hogy nem most merült fel ez az ügy, hanem soksok évvel ezelőtt. Azóta újra és újra megjelenik.
(az ügy ugye a tárolás végességéből és a float ábrázolás mikéntjéből ered)
15

Lebegőpontos, nem pontos

Őry Máté · 2008. Júl. 10. (Cs), 13.47
De ez a probléma nem a round függvénynél kerül elő addig, amíg nem sztringként kell megadni a paramétert. Beírod, hogy 2.135, azt lebegőpontos számként (egy kettes számrendszerű mantissza és egy kettes számrendszerű karakterisztika formájában) dolgozza föl a php. Utána ezt kapja meg a round függvény. Ebben az esetben tízes számrendszerbe váltva éppen 2.135 (vagy mennyi volt) alá kerül a kerekített érték. Ilyenek a lebegőpontos számok.