Re: PHP can't compare...

From: Date: Fri, 07 Dec 2001 18:44:31 +0000
Subject: Re: PHP can't compare...
Groups: php.dev 
Request: Send a blank email to php-dev+get-72886@lists.php.net to get a copy of this message
I guess you didn't understand any of the explanations you got to this. #6220 is not a bug. Computers can not represent floating point values accurately, only to a certain level of precision. Ergo there is no such thing as precisely 0.1 and any function, such as floor(), which relies on a number being precisely greater than some floating point number is never going to work without a little help from the programmer. Bug #6220 is at best a documentation issue. PHP could not possibly do anything to accurately guess the intention of the programmer when it comes to this. You, as a programmer, will have to add the appropriate fuzz factor when using functions such as floor(), ceil() and round(). -Rasmus On Fri, 7 Dec 2001, George Whiffen wrote: > Pierre/Rasmus/Zeev, > > After a little more thought, it seems to me that, my problem, Bug 6220 and Matthew's > original > problem at the start of this thread are all REAL LIVE BUGS. As Pierre suggested, php seems to > handle floating points fine 99% of the time with in its documented precision (14 decimal digits > or > so depending on platform). This is perfectly suitable for nearly any kind of money, > there's no > problem there. > > The real problem is that floor, int, and the comparisons are going beyond this precision. > Explicit > string casts solve this by forcing the floats back to our guaranteed precision at which point > everything works fine! > > I can only guess that internally php carries around as much float precision as it can to > maintain > accuracy on a series of calculations hence > > sprintf("%.50f",(0.7 + 0.1) * 10) is 7.9999999999999991118215802998747676610947 > and > sprintf("%.50f",3.55 + 60.12) is 63.6699999999999945998752082232385873794556 > > Comparison of these floats with 8 and 63.67 respectively fails at this level of precision but > is > fine at 14/15 digits. > > I can see why php would want to carry the extra precision around through calculations but not > when > the float is going in as the argument of an integer returning function/operator such as > floor(), > int(), == or ===. In these cases I take it as a straightforward bug to use more precision than > we > are supposed to be offering. If someone really wants 32 digit precision on comparisons, int, > floor > etc. it should be up to them to go off and explicitly ask for bccomp rather than leaving the > likes > of me to wonder how to explain that 8.2 minus 0.2 is not 8. > > Does that sound ok, or am I exhibiting even more ignorance... > > Unfortunately for me, the one thing I am fairly sure of, is that mysql is completely up the > spout!!! > SELECT IF(0.8 = 0.6 + 0.2,'good database','bad database'); > returns 'bad database' even if you replace the constants with explicit decimal > fields. > > So many, many apologies and much grovelling for ever suggesting that msyql managed to get it > right > while you didn't! Can we re-open 6220 as a bug and attach int, == and === to any > solution? > > Chastened, > > George > > Pierre-Alain Joye wrote: > > > > On Thu, 06 Dec 2001 18:03:23 +0000 > > George Whiffen <george@intellnet.net.uk> wrote: > > > > > Matthew, > > > > > > You are absolutely right, we have to do something about handling money better before > > > anyone else > > > notices that 0.7 plus 0.1 is not 0.8 with php! (I've already had an e-commerce > > > user notice that > > > their account balance is misquoted because 82 - 2 became 79 because of this). > > > > > > Looking through this thread it seems : > > > > > > 1. Floating points are not accurate, floating point arithmetic is not accurate enough > > > for money > > > calculations. > > Wrong, It is fully useable for money. But not for mid-hi precision, use BCmath. > > > > > 2. Zeev is worried that a string based type would create performance problems. > > Don't need to convert to string (huh php don't take really care about type). > > > > > 3. The standard approach when programming in low-level languages such as C or Java, > > > is to convert to > > > "pennies" and rely on integer arithmetic. > > Sure, best way and solve the round problem, I never used more than 5 digits for the > > floating part of a number for money numbers (bank rates and stock calculation). > > > > > 4. bc calculations/comparisons are safe. > > Sure :) > > > > > My questions are: > > > > > > 1. Is it useful to cut down the "money" problem to the bare esentials? e.g. > > > - only handle addition/subtraction/multiplication > > > > > - never worry about more than 2 decimal places > > five is sometimes a must 3 needed especially with euro convertion. > > > > > - maximum values could be practically limited to a billion or so > > As explained in the documentation or type ranges. > > > > > 2. Could we use integer arithmetic for money, given the above restrictions? We only > > > have to spot a > > > "money" field and carry out integer arithmetic rather than floating point > > > arithmetic. Of course we > > > need to multiply the operands by 100 before the addition and divide by 100 at the > > > end. Would that > > > bring back the floating point problem in a new guise? > > Sure it does. This tip were usefull in the past with old rdms systems and improbe indexes > > with actual system (as far you need indexes on amounts). > > > > > 3. How does mysql get away with it? I've never had a smidgeon of trouble with > > > mysql adding > > > decimals. In fact, my "safe" fall back for my bug will be to get mysql to > > > do all the arithmetic > > > rather than php. > > Mysql does not any calculation except when you use function and/or operator. > > Try this : > > select 1.0120000000000001/1 > > and then > > select 1.01200000000000001/1 > > > > Damned 2nd one failed... > > > > > 4. How bad could performance get? How much non-integer, non-money, floating point > > > calculation is > > > really done in php code? Apart from some gd stuff, I can't think when I ever > > > actually do a > > > non-integer, non-money calculation! > > If high precision floating numbers is your need use bcmath or develop your own php modules > > using a dedicated langage or libraries. Float numbers are not finites. See the last Zeev post for > > the link about explanations. > > > > > 5. If actual overall impact on php applications is not too bad, (even if we slow > > > floating point by a > > > factor of ten), could we just use bc routines for all floating point? Perhaps it > > > could be a > > > configuration option, with the default as precise calculation i.e. use bc, and an > > > option for "fast" > > > i.e. non-bc calculation? > > You don't slow down your app. Integer process are generally faster (both in rdbms and > > cpu). > > Except if you have a P4 and you use the Intel Compiler... ;)) > > > > > Let me say again, if we want to be treated seriously as a credible HIGH LEVEL > > > language, let alone a > > > reliable e-commerce platform it is NOT ACCEPTABLE that (int) 10 * 0.7 + 0.1 is 7. It > > > doesn't matter > > > how much documentation we create, it's just not on as default behaviour. So we > > > have to do something! > > Damned ......... > > > > > The alternative is that sooner or later we'll be reading a press release from > > > Seattle that runs > > > something like this... > > > > > > PHP dangerous for e-commerce > > > Reports are coming in of serious failings at e-commerce sites using php. These > > > result from > > > fundamental weaknesses in php's basic arithmetic on monetary figures. > > > Accounting integrity is > > > acknowledged to be completely compromised if developers rely on default php > > > arithmetic. Even > > > calculations such as 8.20 - 0.20 are not dependable. The problems are particularly > > > dangerous > > > because they are intermittent. Php's development team have been aware of this > > > for over a year and > > > despite their much vaunted "open source rapid response", there is no fix, > > > nor even any intention of > > > a fix to this problem. Instead they choose to highlight weaknesses in their > > > underlying C platform. > > > > > > Bigsoft CEO, Robert Doorways comments : This totally vindicates our view that Open > > > Source > > > technologies must not be relied upon for professional corporate applications. Only > > > the most > > > experienced and highly resourced software suppliers have the understanding and > > > capability to deliver > > > to the corporate market. We fully sympathise with customers who have been taken in > > > by the > > > exaggerated claims of the Open Source movement. We have set up a special php > > > translation facilities > > > for everyone who wants to convert their php applications to a more stable language. > > > At BigSoft we > > > have been counting our own and especially other people's money from our earliest > > > days, and are > > > specialists in big money calculations... > > OK but php is fully Y2K compliant ;)). > > > > hth > > > > pa > > -- > > Pierre-Alain Joye > > Freelance > > Developpements et Services web/intranet > > pajoye@tuxfamily.org >

« previous php.dev (#72886) next »