Edit report at https://bugs.php.net/bug.php?id=65485&edit=1

 ID:                 65485
 Comment by:         stephane at it-asia dot com
 Reported by:        stephane at it-asia dot com
 Summary:            Cast gives different values in one way or the other
 Status:             Not a bug
 Type:               Bug
 Package:            *General Issues
 Operating System:   Windows 8 & Mint Maya
 PHP Version:        5.4.18
 Block user comment: N
 Private report:     N

 New Comment:

OK

Thanks for you answer, your time, and everything you do for us.

S.L.


Previous Comments:
------------------------------------------------------------------------
[2013-08-20 17:35:23] [email protected]

Always always always write all apps that deal with money using only integers. 
You 
never work with 17.99 you work with 1799 and only at display time do you add a 
decimal place. All internal manipulation is done using integers without any 
precision loss.

------------------------------------------------------------------------
[2013-08-20 16:40:01] stephane at it-asia dot com

OK, you the boss.

>This is trivial to do in user space.

So what's your recommendation there?

------------------------------------------------------------------------
[2013-08-20 15:19:55] [email protected]

var_dump() is giving you the real value based on your precision setting. If you 
add ini_set('precision',32); to the top of your test script, you will see:

float(3947.9999999999995452526491135359)
float(3948)
int(3947)
int(3948)

And this is exactly the same as C and Python.

And no, there won't be a money type in PHP. This is trivial to do in user space.

------------------------------------------------------------------------
[2013-08-20 13:44:38] stephane at it-asia dot com

Hi Rasmus

Good to find you here.

I understand you follow the C engine. But in C , you have 39.48*100 =  
3947.9999999999995  and in Python, you have 39.48*100 = 3947 when PHP shows 
3948 . 

PHP makes a few more things than that. It is not exactly the same. 

More, when I make tests in the php.ini to increase the precision to 20, the 
float → string gives  3947.9999999999995453  (and 
3947.99999999999954525264911353588104248046875 for a precision of 100)

And the vardump doesn't really give the real full value : it is confusing. 
var_dump (39.48 * 100) => float(3948)   => this is not the real value. 

Better example: 
$d1 = 39.48 * 100;
$d2 = 3948.0;
$i1 = (int) $d1;
$i2 = (int) $d2;

var_dump($d1);
var_dump($d2);
var_dump($i1);
var_dump($i2);

it returns float(3948) float(3948) int(3947) int(3948) 
it should return float(3947.99999999999954525264911353588104248046875) 
float(3948) int(3947) int(3948) 

Can we have a more precise vardump, so we know exactly what happens? I lost 
time because of that. If the vardump gave me  
3947.99999999999954525264911353588104248046875 this morning, I would have 
understood directly what happened. But it gave me 3948, and it is not the real 
value.

I was accustomed to see PHP to provide easy and direct solutions. I don't know 
why, but I was totally convinced we found a way to go over this kind of 
problems. Obviously, talk to any developer around you, nobody never expects to 
see 3948 become 3947 after a cast when a decimal number was involved 100 lines 
before.

In VB6, the result is always 3948 (even for double → int casting ), and they 
have a currency type. SQL server created a "money" type to avoid this kind of 
problems ( http://technet.microsoft.com/en-us/library/ms179882.aspx ). I hate 
saying that, but these guys found  solutions when we still didn't.

Rasmus, can I suggest to consider a new type for “money” treatments? So we 
will still have the normal int and float that match the C standard, and we will 
have something to make time and go directly to the point . For example, a 
“64-bit (8-byte) numbers in an integer format, scaled by 10,000 to give a 
fixed-point number with 15 digits to the left of the decimal point and 4 digits 
to the right”. So (int)39.48*100 will never return 3947 anymore, and brutal 
and lemmings coders like me will make better accountancy software.

Thanks :)

------------------------------------------------------------------------
[2013-08-20 12:08:41] [email protected]

You mean like this in Python:

>>> int(39.48*100)
3947
>>> "%s" % (39.48 * 100)
'3948.0'

This is not PHP-specific in any way.

------------------------------------------------------------------------


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

    https://bugs.php.net/bug.php?id=65485


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=65485&edit=1

Reply via email to