Prevent accurate comparison of floating-point numbers#38
Conversation
460df80 to
a9f590b
Compare
a9f590b to
4f11909
Compare
4f11909 to
07e5b84
Compare
|
Just a note: Edit: Although i guess it depends on how you compute |
|
@ondrejmirtes Here a realistic case where this would cause an issue. function isPaid(array $amounts, array $payments)
{
$total = array_sum($amounts);
$paid = array_sum($payments);
return $paid >= $total;
}
$amounts = [0.1, 0.2];
$payments = [0.15, 0.15];
var_dump(isPaid($amounts, $payments)); // false |
|
@CzechBoy Forbidding floats altogether and avoiding errorneous comparison by equality are two different use cases. |
|
@Majkl578 sure, I only send link to similiar library. |
|
Hi, I'm not sure about this one, I worry it'd be too annoying. AFAIK floats are precise to a certain number of decimals so for example if you compare two floats after rounding them to one decimal place (like But feel free to publish this as a separate package, I'm certain some people would like it. I'm gonna wait some time before closing for feedback from the others. |
The (need of / absence of) rounding in first place is the problem here as it's something people usually don't do / forget. php > var_dump(.1 + .2 == .3);
bool(false)IMO PHPStan should warn about this code, possibly directly in core, not only in phpstan-strict-rules. 🤔 https://andy-carter.com/blog/don-t-trust-php-floating-point-numbers-when-equating |
|
The linked article shows that |
Not sure I find an article recommending |
@dmytro-dymarchuk What about the comparison with Can we have unexpected behavior with code like Or should it be a special case ignored by your rule ? |
$floatAmount1 = 0.1;
$floatAmount2 = 0.2;
$sumFloat = $floatAmount1 + $floatAmount2;
echo "Sum using float: $sumFloat\n"; // Output: Sum using float: 0.30000000000000004
$stringAmount1 = '0.1';
$stringAmount2 = '0.2';
$sumString = bcadd($stringAmount1, $stringAmount2, 1);
echo "Sum using string: $sumString\n"; // Output: Sum using string: 0.3So yeah, either bcmath and strings, or better yet a value object: |
|
Having caused myself some serious headaches with float comparisons that work in some situations but not others, I'd be very much behind this being included here. I don't see it as being any more annoying than requiring booleans in conditionals. |
Prevent situation when comparison return can unexpected result. For example: