Re: [PHP] Beware of round() function
On Mon, 24 Mar 2008 13:10:17 -0600, [EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. For certain special numbers that seem to be multiples of 100,000, the return value is in exponential format, rather than the usual decimal format. Some of these special values are 120, 140, 230, which are returned as 1.2E+6, 1.4E+6, etc. You can generate your own list of these special numbers using this code: ?php for( $tmp = 0, $i = 0; $i 100; $i++ ) { $tmp += 10; echo round($tmp),\n; } ? I now have a list of 3 ways this change in behavior can bite you and result in a failed transaction. In the examples below, assume that the value passed to round() is '120', so that the value returned from round() is '1.2E+6'. 1. When interpolating the value into xml, resulting in an xsd validation error: ? $xml = 'AnnualIncome' . round($income) . '/AnnualIncome'; ? 2. When validating user input, resulting in a false positive: ? if(!ereg(^[0-9]{1,10}$, round($_POST['income']))) { $errors .= liIncome should be whole dollars only (10 digits max)./li; } ? 3. When interpolating a value into a stored procedure call, resulting in a type mismatch between the value passed in and the database column data type (which is likely decimal for a monetary value): ? $sql = exec update_loan_financials @application_id='$appID', @total_debt= . round($totalDebt); ? BTW, a previous poster pointed out that this is a change in behavior of the float type, in general, not of the round() function, in particular. If you care. I don't. I just know I have broken code to fix and customers to apologize to. Kirk -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
[EMAIL PROTECTED] wrote: On Mon, 24 Mar 2008 13:10:17 -0600, [EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. For certain special numbers that seem to be multiples of 100,000, the return value is in exponential format, rather than the usual decimal format. Some of these special values are 120, 140, 230, which are returned as 1.2E+6, 1.4E+6, etc. You can generate your own list of these special numbers using this code: ?php for( $tmp = 0, $i = 0; $i 100; $i++ ) { $tmp += 10; echo round($tmp),\n; } ? I now have a list of 3 ways this change in behavior can bite you and result in a failed transaction. In the examples below, assume that the value passed to round() is '120', so that the value returned from round() is '1.2E+6'. 1. When interpolating the value into xml, resulting in an xsd validation error: ? $xml = 'AnnualIncome' . round($income) . '/AnnualIncome'; ? 2. When validating user input, resulting in a false positive: ? if(!ereg(^[0-9]{1,10}$, round($_POST['income']))) { $errors .= liIncome should be whole dollars only (10 digits max)./li; } ? For the above test, is there any reason you couldn't use is_numeric() Looks like it would work in this case. ?php if ( ! is_numeric($_POST['income']) ) { $errors .= liIncome should be whole dollars only . (10 digits max)./li; } ? 3. When interpolating a value into a stored procedure call, resulting in a type mismatch between the value passed in and the database column data type (which is likely decimal for a monetary value): ? $sql = exec update_loan_financials @application_id='$appID', @total_debt= . round($totalDebt); ? BTW, a previous poster pointed out that this is a change in behavior of the float type, in general, not of the round() function, in particular. If you care. I don't. I just know I have broken code to fix and customers to apologize to. Kirk -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
At 10:55 AM -0600 3/25/08, [EMAIL PROTECTED] wrote: Thanks for the info, Jeremy. Regardless of the technical details, my code still broke. I am little discouraged that an operation that should be so simple has these sorts of gotchas. Not that this helps/hurts your observation. What I find interesting is that the round function has a bias to round down. I've proved it, but it takes a lot of calculations to demonstrate any significant difference. Cheers, tedd -- --- http://sperling.com http://ancientstones.com http://earthstones.com -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
Thanks for the info, Jeremy. Regardless of the technical details, my code still broke. I am little discouraged that an operation that should be so simple has these sorts of gotchas. BTW, I ended up casting to int as my solution. Kirk Jeremy Privett [EMAIL PROTECTED] wrote on 03/24/2008 02:04:48 PM: Jeremy Privett wrote: [EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. This is actually a change in the behavior of the float type, not the round function. Replace your round() with a cast to float and you'll see the exact same result. Also, as a side-note, the only way I've found to get these numbers to print properly is through either printf or sprintf. Also, you could cast back to an integer, if you explicitly don't need floats. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP] Beware of round() function
Beware: round() apparently has changed its behavior from PHP 4. For certain special numbers that seem to be multiples of 100,000, the return value is in exponential format, rather than the usual decimal format. Some of these special values are 120, 140, 230, which are returned as 1.2E+6, 1.4E+6, etc. You can generate your own list of these special numbers using this code: ?php for( $tmp = 0, $i = 0; $i 100; $i++ ) { $tmp += 10; echo round($tmp),\n; } ? The exponential format is fine as long as the number is only used internally to PHP. However, we have found two cases so far where the exponential format has caused errors resulting in failed transactions. One, if you interpolate a value in exponential format into xml, as in this example, then you will likely end up with an xsd validation error and a failed transaction: 'AnnualIncome' . round($income) . '/AnnualIncome' Two, if you have field validation code like below, this will falsely indicate an error when the consumer enters one of the special values for income, e.g., 120, which is returned as 1.2E+6: if(!ereg(^[0-9]{1,10}$, round($_POST['income']))) { $errors .= liIncome should be whole dollars only (10 digits max)./li; } Needless to say, not a good user experience. I reported this as a bug to the PHP dev team, but it was rejected. Regardless of what it is, it will bite you if you're not careful. http://bugs.php.net/?id=44223edit=2 - Kirk -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
[EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. This is actually a change in the behavior of the float type, not the round function. Replace your round() with a cast to float and you'll see the exact same result. -- Jeremy Privett C.E.O. C.S.A. Omega Vortex Corporation http://www.omegavortex.net Please note: This message has been sent with information that could be confidential and meant only for the intended recipient. If you are not the intended recipient, please delete all copies and inform us of the error as soon as possible. Thank you for your cooperation. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
Jeremy Privett wrote: [EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. This is actually a change in the behavior of the float type, not the round function. Replace your round() with a cast to float and you'll see the exact same result. Also, as a side-note, the only way I've found to get these numbers to print properly is through either printf or sprintf. Also, you could cast back to an integer, if you explicitly don't need floats. -- Jeremy Privett C.E.O. C.S.A. Omega Vortex Corporation http://www.omegavortex.net Please note: This message has been sent with information that could be confidential and meant only for the intended recipient. If you are not the intended recipient, please delete all copies and inform us of the error as soon as possible. Thank you for your cooperation. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] Beware of round() function
On Mon, 24 Mar 2008 13:10:17 -0600, [EMAIL PROTECTED] wrote: Beware: round() apparently has changed its behavior from PHP 4. For certain special numbers that seem to be multiples of 100,000, the return value is in exponential format, rather than the usual decimal format. Some of these special values are 120, 140, 230, which are returned as 1.2E+6, 1.4E+6, etc. You can generate your own list of these special numbers using this code: ?php for( $tmp = 0, $i = 0; $i 100; $i++ ) { $tmp += 10; echo round($tmp),\n; } ? Use (int)round($tmp) to get integer format. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php