Strahan Posted November 10, 2012 Share Posted November 10, 2012 I'm assuming I'm perhaps suffering from some sort of type issue, but I can't figure this out. I pay my ex girlfriend to do housework for me. We were using a spreadsheet to track her hours and stuff, but I figured since I love tinkering with PHP this would be a good thing to convert to a web app. Everything is good, but when I wrote the payroll history report I'm having a problem. This is the code: case "payhistory": $sql = $pdo->query("SELECT * FROM hours WHERE paid IS NOT NULL ORDER BY paid"); $subpay = 0; $subhrs = 0; $curpd = ""; $totpay = 0; $tothrs = 0; $subhrs = 0; while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { if ($curpd != $row["paid"]) { if (!empty($curpd)) { Write("<BR><BR>SUBTOTAL: $subpay"); $actualpay = getpay($payid); if ($actualpay <> $subpay && !empty($actualpay)) Write("<BR><I>(" . money($actualpay) . ")</i>"); Write("<BR><HR>"); } $subpay = 0; $subhrs = 0; $curpd = $row["paid"]; $payid = $row["payid"]; } if ($row["debt_incurred"] == "0") { Write("Hours: " . sec2time(strtotime($row["ended"]) - strtotime($row["started"])) . ", pay: " . pay_amount($row["started"], $row["ended"]) . "<BR>"); $totpay += pay_amount($row["started"], $row["ended"]); $tothrs += strtotime($row["ended"]) - strtotime($row["started"]); $subpay += pay_amount($row["started"], $row["ended"]); $subhrs += strtotime($row["ended"]) - strtotime($row["started"]); } else { if ($row["debt_incurred"] > 0) { $totpay -= $row["debt_incurred"]; $subpay -= $row["debt_incurred"]; } else { $totpay += str_replace("-", "", $row["debt_incurred"]); $subpay += str_replace("-", "", $row["debt_incurred"]); } Write("Debt: {$row["debt_reason"]}, amount: {$row["debt_incurred"]}<BR>"); } } Write("<BR><BR>SUBTOTAL: $subpay"); $actualpay = getpay($payid); if ($actualpay <> $subpay && !empty($actualpay)) Write("<BR><I>(" . money($actualpay) . ")</i><BR><BR>"); Write("|$subpay| |$actualpay|<BR><BR>"); if ("|$subpay|" != "|$actualpay|") { Write("Does NOT match!<BR>"); } else { Write("Matches!<BR>"); } if ($subpay != $actualpay) { Write("Does NOT match!<BR>"); } else { Write("Matches!<BR>"); } if (floatval($subpay) != floatval($actualpay)) { Write("Does NOT match!<BR>"); } else { Write("Matches!<BR>"); } if (floatval($subpay) <> floatval($actualpay)) { Write("Does NOT match!<BR>"); } else { Write("Matches!<BR>"); } break; I've removed a bunch of the formatting junk to make it less bulky, but that's it. It loops through my data and breaks on a change in "paid", the field that marks the date that work was paid for. I subtotal the amount earned in $subpay during the looping. I have a function getpay that makes a call to a separate table to get the amount I actually paid (sometimes the actual amt I pay her is different than the tallied hours). It returns that to $actualpay then it compares and if they aren't matched up, it prints the subpay with the actualpay beneath it in italics. Works great until the last record. I get this output: Debt: Dollar Tree, amount: 4.12 Debt: Fax, amount: 20.00 Hours: 45 minutes, pay: 11.25 Hours: 1 hour, pay: 15 Hours: 45 minutes, pay: 11.25 Hours: 30 minutes, pay: 7.5 Hours: 30 minutes, pay: 7.5 Hours: 15 minutes, pay: 3.75 Debt: Phone card, amount: 47.00 Hours: 1 hour, pay: 15 Hours: 30 minutes, pay: 7.5 Debt: Loan to me, amount: -30.00 SUBTOTAL: 37.63 ($37.63) |37.63| |37.63| Matches! Does NOT match! Does NOT match! Does NOT match! It matches the two if I make them strings but I can't figure out how to match them otherwise. I'm sure it's a dumb mistake on my part, but it's one I cannot find and it drives me nuts because the same code works fine during the loop, it just dies outside of it. ?? Quote Link to comment https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/ Share on other sites More sharing options...
Barand Posted November 10, 2012 Share Posted November 10, 2012 (edited) Comparing floats is often a problem. You mays actually be trying to match 12.3400000000001 = 12.3399999999999999 The best way is to see if the difference is acceptably small if (abs($a - $b )< 0.000001) { // equal as far as I am concered } Edited November 10, 2012 by Barand Quote Link to comment https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/#findComment-1391538 Share on other sites More sharing options...
Strahan Posted November 10, 2012 Author Share Posted November 10, 2012 Comparing floats is often a problem. You mays actually be trying to match 12.3400000000001 = 12.3399999999999999 The best way is to see if the difference is acceptably small if (abs($a - $b )< 0.000001) { // equal as far as I am concered } I changed to the ABS method and the problem went away. Pesky floats! Thanks a lot! Quote Link to comment https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/#findComment-1391541 Share on other sites More sharing options...
PFMaBiSmAd Posted November 10, 2012 Share Posted November 10, 2012 You should also change your database columns to DECIMAL so that the values will be stored as an exact value, rather than being converted to floating point. Quote Link to comment https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/#findComment-1391548 Share on other sites More sharing options...
Strahan Posted November 10, 2012 Author Share Posted November 10, 2012 Switched it. Thanks for the tip! Quote Link to comment https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/#findComment-1391619 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.