Re: [PHP] Beware of round() function

2008-04-09 Thread Kirk . Johnson
 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

2008-04-09 Thread Jim Lucas

[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

2008-03-26 Thread tedd

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

2008-03-25 Thread Kirk . Johnson
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

2008-03-24 Thread Kirk . Johnson
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

2008-03-24 Thread Jeremy Privett

[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

2008-03-24 Thread Jeremy Privett

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

2008-03-24 Thread Martín Marqués

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