![](/img/trans.png)
[英]What is the best way to bind decimal / double / float values with PDO in PHP?
[英]What is the best way to convert a decimal (float) to an integer?
我試圖將包含小數的浮點數相乘並得到不正確的結果。
比如下面的代碼計算不正確......
$value = (int) (600.55 * 100);
var_dump($value); // outputs the number 60054 when it should be 60055
我能夠通過使用 str_replace 刪除小數來解決問題...
$value = str_replace('.', '', 600.55);
var_dump($value); // now outputs the correct number 60055
但我想知道是否有更合適的方法將小數(浮點數)轉換為 integer,這樣我就可以在不改變數字的情況下進行基本的數學運算
讓我們了解為什么您會得到60054
。
<?php
$value = 600.55 * 100;
printf('%.18f', $value);
output 是: 60054.999999999992724042
。
$value
是一個浮點數。 如您所料,它的值可能不會在 memory 中表示。 這是一個近似值。 這就是為什么,例如,使用浮點數來賺錢是一個非常糟糕的主意。 地理坐標可能沒問題。
為什么$value = str_replace('.', '', 600.55);
似乎工作正常?
<?php
echo 600.55;
output 是: 600.55
。
<?php
printf('%.18f', 600.55);
output 是: 600.549999999999954525
。
<?php
$value = 600.55;
printf('%s => %.18f', $value, str_replace('.', '', $value));
output 是: 600.55 => 60055.000000000000000000
。
<?php
echo str_replace('.', '', 600.5599999999999);
output 是: 60056
。
當浮點數轉換為字符串時,字符串不包含所有十進制數字。 你會得到一個“有根據的猜測”。 在您的情況下, 600.55
被隱式轉換為"600.55"
,因為 function str_replace
的 arguments 應該是字符串。
那你該怎么辦?
如果您只想將一個數字乘以 100,則四舍五入似乎可以正常工作:
<?php
$value = (int)round(123.45 * 100);
var_dump($value);
output 是: int(12345)
。
注意:我讀了一條評論說round(600.123 * 100);
給出600122
而不是600123
。 發生這種情況是因為 600.123 的十進制數多於兩位,而最后一位小於 5。
但是,如果您正在執行大量操作,它可能會失敗:
$value = 0;
for ($i = 0; $i < 50; ++$i) {
$value += .2;
}
var_dump((int)$value, .2 * 50);
output 是: int(9) float(10)
。
有一個數學擴展BCMath來處理需要精度的十進制數的運算。 它使用字符串來表示數字:
<?php
$value = bcmul('600.55', '100');
var_dump($value);
output 是: string(5) "60055"
。
如果性能是優先事項,您還可以實現一種表示定點數的方法。 或拆分 integer 和小數邊:
<?php
$integer = 600;
$decimal = 55;
$value = $integer * 100 + $decimal;
output 是: int(60055)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.