Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Adakah Penyelesaian `ketepatan` PHP Boleh Dipercayai untuk Pengiraan Wang 2 Digit Yang Tepat?

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

Linda Hamilton
Linda Hamiltonasal
2024-11-07 06:39:02542semak imbas

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)

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)

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)

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!

Kenyataan:
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