Jump to content

Numbers Do Not Match Yet They Do


Strahan

Recommended Posts

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.

 

??

Link to comment
https://forums.phpfreaks.com/topic/270539-numbers-do-not-match-yet-they-do/
Share on other sites

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

}

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!

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.