ID: 47418 Comment by: tdietsche at comcast dot net Reported By: cu19 at gmx dot de Status: Open Bug Type: *Math Functions Operating System: Win7 PHP Version: 5.3.1 New Comment:
/* set up an Excel 97-2003 spreadsheet with a worksheet 'Nov' and the row headers below on row 3 then add a row 14 with "John Smith" in Tenant, "11" in Lot, and "19" in Late Fee. Late fee should be number format with 2 decimals and comma thousands separator format. Create an odbc system DSN called "rent_2009" linked to it. Then run this script against it, I have stripped it down but I think it will show the problem. note this will NOT show the problem if you just supply variable values directly, it has to come from excel and has something to do with the (string) casting of values that excel thinks are numbers. somehow the float and string are getting goofed up. Even when I fixed the value, the total it was being added to still had the problem until I hardwired a second test on "18.:0" to fix that. Jeez. (row headers): Tenant Lot Prev Bal Rent LP Gas Taxes Garbage Elec CR Mowing Late Fee Misc Deposit New Bal Check Cash Mail Bal Fwd Last Mon This Mon Change Factor Gallons Rate/Gal LP Amt NOTES Misc Desc */ $result = ''; $month_total = 0; $totals = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); function FmtFieldAmt($tot_num, $field_name) { global $result, $month_total, $totals; $res = odbc_result($result, $field_name); $fld_amt = GetDec($res); $fmt_amt = FmtAmt($fld_amt); $month_total += $fmt_amt; $totals[$tot_num] += $fmt_amt; return $fmt_amt; } function GetDec($value) { if ($value == null || (string)$value == '') return 0; else return $value; } function FmtAmt($amt) { if ((string)$amt == '18.:') $amt = '19'; // another workaround for the total $cred = ' '; if ($amt < 0) { $amt = 0 - $amt; $cred = 'CR'; } // $amt = number_format($amt, 2) . $cred; // uncomment this comment out next line to see bug $ret = stupid_php($amt) . $cred; return $ret; } // this is my workaround which works if the value doesn't already have the stupid colon in it function stupid_php($val) { $len = strlen($val); if ($len == 0) return $val; if (strpos($val, '.') == false) return $val . '.00'; // for 123.4 len=5 pos=3 return 123.45 if (strpos($val, '.') == $len - 2) return $val . '0'; if (strpos($val, '.') < $len - 2) return round($val, 2); return $val; } function jsi_db_error($query, $errno, $error) { exit ('**Database Error (' .$errno. ') ' .$error. ' Query=[' .$query. '] **'); } $db_name = 'rent_2009'; $link = odbc_connect($db_name, 'user', 'pw') or jsi_db_error('Connect', odbc_errormsg(), odbc_error() ); $query = 'SELECT * FROM [Nov$A3:Z43] WHERE Lot = 11'; $result = odbc_exec($link, $query) or jsi_db_error($query, odbc_errormsg(), odbc_error()); echo FmtFieldAmt(6, 'Late Fee'); echo FmtAmt($totals[6]); Previous Comments: ------------------------------------------------------------------------ [2010-02-12 11:55:25] cu19 at gmx dot de That's nothing different, but exactly the same problem as I described from the beginning. This is the function that I currently use as a workaround. It works fine, but I would prefer php doing this itself... function my_number_format ($number, $decimals=0, $dec_point=',', $thousands_sep='.') { $string = number_format($number, $decimals, $dec_point, $thousands_sep); $pos = strlen($string) - 1; $increase = false; while ($pos >= 0) { if (($increase) and (is_numeric($string{$pos}))) { $string{$pos} = chr(ord($string{$pos}) + 1); $increase = false; } if ($string{$pos} == ':') { $string{$pos} = '0'; $increase = true; } $pos--; } if ($increase) $string = '1' . $string; return $string; } ------------------------------------------------------------------------ [2010-02-12 11:37:38] paj...@php.net For the garbage problem, that's something else. Can you provide a reproduce script (with data) please? ------------------------------------------------------------------------ [2010-02-12 11:31:41] tdietsche at comcast dot net this sure IS a bug, scott_mac you need to wake up, if this is the best that php handles floating point then it is worthless. In reading a value of "19" from an excel spreadsheet via odbc, it formats it as "18.:0" which is pure garbage and a bug to me. How can you defend that? I can send my code if you want. ------------------------------------------------------------------------ [2009-02-25 01:00:01] php-bugs at lists dot php dot net No feedback was provided for this bug for over a week, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open". ------------------------------------------------------------------------ [2009-02-17 11:20:31] scott...@php.net sc...@skinny [~] $ php -r 'var_dump(number_format(3.9, 2));' string(4) "3.90" Can't reproduce this on Linux. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/47418 -- Edit this bug report at http://bugs.php.net/?id=47418&edit=1