RESAZIP-PC\resaz

add daitomath

...@@ -50,3 +50,43 @@ composer require daito/lib:^1.0 ...@@ -50,3 +50,43 @@ composer require daito/lib:^1.0
50 # or 50 # or
51 composer update daito/lib 51 composer update daito/lib
52 ``` 52 ```
53 +
54 +## Performance note (DaitoMath)
55 +
56 +`DaitoMath` uses `brick/math` for precise decimal calculations (financial-safe).
57 +
58 +- It can run without extra PHP extensions.
59 +- For better performance on production, enable one of:
60 + - `ext-gmp` (recommended)
61 + - `ext-bcmath`
62 +- `brick/math` will automatically use the fastest available calculator at runtime.
63 +
64 +Quick check:
65 +
66 +```bash
67 +php -m | grep -Ei "gmp|bcmath"
68 +```
69 +
70 +Install extensions if missing:
71 +
72 +```bash
73 +# Ubuntu / Debian
74 +sudo apt-get update
75 +sudo apt-get install -y php-gmp php-bcmath
76 +sudo systemctl restart php8.2-fpm || sudo systemctl restart apache2
77 +```
78 +
79 +```bash
80 +# CentOS / RHEL / Rocky / AlmaLinux
81 +sudo yum install -y php-gmp php-bcmath
82 +sudo systemctl restart php-fpm || sudo systemctl restart httpd
83 +```
84 +
85 +```powershell
86 +# Windows (php.ini)
87 +# 1) Open php.ini
88 +# 2) Enable these lines:
89 +extension=gmp
90 +extension=bcmath
91 +# 3) Restart web server / PHP-FPM service
92 +```
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -8,7 +8,12 @@ ...@@ -8,7 +8,12 @@
8 } 8 }
9 }, 9 },
10 "require": { 10 "require": {
11 + "brick/math": "^0.9 || ^0.10 || ^0.11 || ^0.13",
11 "php": "^7.3 || ^8.0", 12 "php": "^7.3 || ^8.0",
12 "laravel/framework": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0" 13 "laravel/framework": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0"
14 + },
15 + "suggest": {
16 + "ext-gmp": "Faster big-number calculations",
17 + "ext-bcmath": "Faster decimal calculations when GMP is unavailable"
13 } 18 }
14 } 19 }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 "This file is @generated automatically" 5 "This file is @generated automatically"
6 ], 6 ],
7 - "content-hash": "f0e944fbfbea5c3b7cd02a9cd33e3cea", 7 + "content-hash": "0c23b9705a5fe293b678d1bbc5020207",
8 "packages": [ 8 "packages": [
9 { 9 {
10 "name": "brick/math", 10 "name": "brick/math",
......
1 +<?php
2 +
3 +namespace Daito\Lib;
4 +
5 +use Brick\Math\BigDecimal;
6 +use Brick\Math\Exception\DivisionByZeroException;
7 +use Brick\Math\RoundingMode;
8 +use RuntimeException;
9 +
10 +class DaitoMath
11 +{
12 + const DEFAULT_SCALE = 12;
13 +
14 + public static function add($left, $right, $scale = self::DEFAULT_SCALE)
15 + {
16 + $bigDecimal = self::toBigDecimal($left)->plus(self::toBigDecimal($right));
17 +
18 + return self::normalize((string) $bigDecimal->toScale((int) $scale));
19 + }
20 +
21 + public static function sub($left, $right, $scale = self::DEFAULT_SCALE)
22 + {
23 + $bigDecimal = self::toBigDecimal($left)->minus(self::toBigDecimal($right));
24 +
25 + return self::normalize((string) $bigDecimal->toScale((int) $scale));
26 + }
27 +
28 + public static function mul($left, $right, $scale = self::DEFAULT_SCALE)
29 + {
30 + $bigDecimal = self::toBigDecimal($left)->multipliedBy(self::toBigDecimal($right));
31 +
32 + return self::normalize((string) $bigDecimal->toScale((int) $scale));
33 + }
34 +
35 + public static function div($left, $right, $scale = self::DEFAULT_SCALE)
36 + {
37 + $leftValue = self::toBigDecimal($left);
38 + $rightValue = self::toBigDecimal($right);
39 +
40 + if ($rightValue->isZero()) {
41 + throw new RuntimeException('Can not divide by zero.');
42 + }
43 +
44 + try {
45 + $bigDecimal = $leftValue->dividedBy($rightValue, (int) $scale, RoundingMode::HALF_UP);
46 + } catch (DivisionByZeroException $exception) {
47 + throw new RuntimeException('Can not divide by zero.');
48 + }
49 +
50 + return self::normalize((string) $bigDecimal);
51 + }
52 +
53 + public static function floor($value)
54 + {
55 + return (string) self::toBigDecimal($value)->toScale(0, RoundingMode::FLOOR);
56 + }
57 +
58 + public static function ceil($value)
59 + {
60 + return (string) self::toBigDecimal($value)->toScale(0, RoundingMode::CEILING);
61 + }
62 +
63 + public static function round($value, $scale = 0)
64 + {
65 + return self::normalize((string) self::toBigDecimal($value)->toScale((int) $scale, RoundingMode::HALF_UP));
66 + }
67 +
68 + public static function mulFloor($left, $right, $scale = self::DEFAULT_SCALE)
69 + {
70 + return self::floor(self::mul($left, $right, $scale));
71 + }
72 +
73 + private static function toBigDecimal($value)
74 + {
75 + if (is_int($value) || is_string($value)) {
76 + return BigDecimal::of((string) $value);
77 + }
78 +
79 + if (is_float($value)) {
80 + return BigDecimal::of(self::normalize(sprintf('%.14F', $value)));
81 + }
82 +
83 + throw new RuntimeException('DaitoMath only supports int, float, or numeric string.');
84 + }
85 +
86 + private static function normalize($number)
87 + {
88 + $number = (string) $number;
89 + if (strpos($number, '.') === false) {
90 + return $number;
91 + }
92 +
93 + $number = rtrim($number, '0');
94 + $number = rtrim($number, '.');
95 +
96 + if ($number === '-0') {
97 + return '0';
98 + }
99 +
100 + return $number === '' ? '0' : $number;
101 + }
102 +}