Adakah Penyelesaian `ketepatan` PHP Boleh Dipercayai untuk Pengiraan Wang 2 Digit Yang Tepat?

Linda Hamilton
Lepaskan: 2024-11-07 06:39:02
asal
542 orang telah melayarinya

Is PHP's `precision` Workaround Reliable for Precise 2-Digit Money Calculations?

Bolehkah saya Bergantung pada PHP PHP.INI Penyelesaian Ketepatan untuk Isu Titik Terapung?

Pengenalan

Aritmetik titik terapung melibatkan mewakili nombor pecahan sebagai perduaan pecahan, yang mungkin tidak mempunyai perwakilan yang tepat. Ini boleh membawa kepada ralat pembundaran.

Soalan 1:

Bolehkah penyelesaian ini memastikan pengiraan 2 digit yang tepat untuk wang?

Jawapan 1:

Tidak. Tetapan ketepatan PHP tidak dapat menjamin pengiraan 2 digit yang tepat, kerana ketepatan boleh ditingkatkan semasa pengiraan.

Soalan 2:

Contoh apabila penyelesaian gagal:

ini_set('precision', 8);
$a = 5.88; // cost of 1kg
$q = 2.49; // User buys 2.49 kg
$b = $a * 0.01; // 10% Discount only on first kg
echo ($a * $q) - $b; // result: 14.5824 (not precise for money calculations)
Salin selepas log masuk

Soalan 3:

Nilai php.ini.precision yang manakah paling sesuai untuk pengiraan wang 2 digit?

Jawapan 3:

Ketepatan PHP ialah bukan metrik yang disyorkan untuk pengiraan kewangan yang tepat.

Ujian Mudah

Menggunakan bcmath, format_nombor dan penolakan:

$a = 342349.23;
$b = 341765.07;

ini_set('precision', 20);
echo $a - $b, PHP_EOL; // 584.15999999997438863
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.15999999999996817 (rounding issue)
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.15 (precision set to 20)

ini_set('precision', 14);
echo $a - $b, PHP_EOL; // 584.15999999997
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.16 (precision set to 14)

ini_set('precision', 6);
echo $a - $b, PHP_EOL; // 584.16
echo floatval(round($a - $b, 2)), PHP_EOL; // 584.16
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 584.00 (precision set to 6)

ini_set('precision', 3);
echo $a - $b, PHP_EOL; // 584
echo floatval(round($a - $b, 2)), PHP_EOL; // 584
echo number_format($a - $b, 2), PHP_EOL; // 584.16
echo bcsub($a, $b, 2), PHP_EOL; // 0.00 (precision set to 3)
Salin selepas log masuk

Kesimpulan

Menggunakan format_nombor untuk pengiraan wang disyorkan untuk konsistensi. Menyimpan dalam sen juga merupakan pilihan.

Kemas kini

Soalan 1: Adakah penyelesaian ketepatan akan gagal untuk nombor antara 0..999999.99?

Jawapan 1:

Ya, disebabkan bilangan kombinasi yang banyak, ujian penuh adalah tidak praktikal.

Contoh:

$a = 0.19;
$b = 0.16;
...
$h = $a + $b + ...; // Total value: 0.4

$i = $h - $a - $b - ...; // Result: 1.0408341E-17 (expected: 0.00)
Salin selepas log masuk

Soalan 2: Bagaimana untuk menganggarkan apabila penyelesaian ketepatan gagal?

Jawapan 2:

Penyelesaian matematik wujud, tetapi ia bukan dalam skop perbincangan ini.

Atas ialah kandungan terperinci Adakah Penyelesaian `ketepatan` PHP Boleh Dipercayai untuk Pengiraan Wang 2 Digit Yang Tepat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!