Jump to content

[SOLVED] 49.95 doesn't equal 49.95, what?


danbopes

Recommended Posts

Take a look at this, I am completely and utterly stumped.  I have about 5 years of experience, and I really believe I have come across a bug.

 

Inside of an object:
fwrite($logFd, $this->my_var_dump((floatVal('49.95') == floatVal('49.95'))));
$my_total = ($_POST['mc_gross'] + ($this->account_total($user_id)));
$test = $this->my_var_dump($my_total == $total);
$test2 = $this->my_var_dump($my_total);
$test3 = $this->my_var_dump($total);
fwrite($logFd, $test . ',' . $test2 . ',' . $test3);

$this->my_var_dump($var) simply just dumps the var, to a variable instead of to the browser.  Refer to var_dump on the php website.  This is what I get in the file:

bool(true)
bool(false)
,float(49.95)
,float(49.95)

 

I am seriously like WTF.

 

$this->account_total simply pulls from a database:

function account_total($user_id)
{
	// BE SURE TO GET A FRESH ROW!  $this->user->user_info is session based, and may not be up to date!
	$row = $this->db->getRow("SELECT `account_type`, `static_balance`, `dynamic_balance` FROM `users` WHERE `id` = " . $user_id);

	if ( empty($row) )
		return '0.00';

	if ( $row['account_type'] > 1 )
		return number_format($row['static_balance'] + $row['dynamic_balance'], 2);
	else
		return '0.00';

}

 

I just want to add them up and do a bit of checking, but idk whats wrong.

Link to comment
Share on other sites

<?php
$_POST['mc_gross'] = '0.80';

class paypal_IPN
{
function process()
{
	$total = 49.95;

	$my_total = ($_POST['mc_gross'] + ($this->account_total($user_id)));
	var_dump($my_total == $total);
	var_dump($my_total);
	var_dump($total);
}

function account_total($user_id)
{
	return 49.15;
}
} //end of class

$index = new PayPal_IPN();
$index->process();
?>

Link to comment
Share on other sites

<?php

$a = '14.95';
$b = 14.95;

var_dump( $a == $b );		# bool(true)
var_dump( $a === $b );		# bool(false)
var_dump( (float)$a === $b );	# bool(true)

?>

 

Do you even look at my code before you post?  They are both floats...and I am checking to see if they are equal...why are you bringing in '===' to this?

Link to comment
Share on other sites

Wow.  Just figured something out, and I think you're right about there being a bug.  I think PHP doesn't want to handle float equality correctly (not sure why), because if you typecast to a string, you get the correct result:

 

<?php
$_POST['mc_gross'] = '0.80';

class paypal_IPN
{
function process()
{
	$total = 49.95;

	$my_total = ($_POST['mc_gross'] + ($this->account_total($user_id)));
	var_dump($my_total);
	var_dump($total);
	if ((string) $total == (string) $my_total) {
		echo "Same\n";
	}
	else {
		echo "Not the same\n";
	}

}

function account_total($user_id)
{
	return 49.15;
}
} //end of class

$index = new PayPal_IPN();
$index->process();
?>

Link to comment
Share on other sites

Nope, this makes sense... read up on float precision... To sum it up, binary data can't store a decimal number 'properly' so as soon as you add a number to it, you're gonna have inaccuracies that may not be present in 2-decimal accuracy

 

Use this to correct it.

var_dump((string)$my_total == (string)$total);

 

Do you even look at my code before you post?  They are both floats...and I am checking to see if they are equal...why are you bringing in '===' to this?

 

I posted before I noticed you had replied.

Link to comment
Share on other sites

It's not solved, because I need to check to see if it's greater then or equal to, not equal to.  We are dealing with small numbers here, I don't see why it would be messing up this badly.  0.80 + 49.15 is 49.95, I don't see how that can be any other thing.  Both var_dumps are telling me it's both a float at 49.95, there is no reason this shouldn't be working.

Link to comment
Share on other sites

It's not solved, because I need to check to see if it's greater then or equal to, not equal to.  We are dealing with small numbers here, I don't see why it would be messing up this badly.  0.80 + 49.15 is 49.95, I don't see how that can be any other thing.  Both var_dumps are telling me it's both a float at 49.95, there is no reason this shouldn't be working.

 

Learn how computers store float values as binary data, and you will find the reason. Why do you think most database engines have both FLOAT and DECIMAL type columns?

Link to comment
Share on other sites

It's not solved, because I need to check to see if it's greater then or equal to, not equal to.  We are dealing with small numbers here, I don't see why it would be messing up this badly.  0.80 + 49.15 is 49.95, I don't see how that can be any other thing.  Both var_dumps are telling me it's both a float at 49.95, there is no reason this shouldn't be working.

 

Learn how computers store float values as binary data, and you will find the reason. Why do you think most database engines have both FLOAT and DECIMAL type columns?

 

Oh oh, I know!  Pick me, pick me!  Pleeeeeeease! :D  Anyway, yeah, don't gripe about it if you don't understand what's actually going on.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.