@@ -65,14 +65,15 @@ class Decimal implements JsonSerializable, Stringable
6565 /**
6666 * @param object|string|float|int $value
6767 * @param int|null $scale Decimal places in the result. Omit to enable auto-detection.
68+ * @param bool $strict If scale should be strictly checked to avoid accidental precision loss.
6869 */
69- public function __construct (object |string |float |int $ value , ?int $ scale = null )
70+ public function __construct (object |string |float |int $ value , ?int $ scale = null , bool $ strict = false )
7071 {
7172 $ value = $ this ->parseValue ($ value );
7273 $ value = $ this ->normalizeValue ($ value );
7374
7475 $ this ->setValue ($ value , $ scale );
75- $ this ->setScale ($ scale );
76+ $ this ->setScale ($ scale, $ strict );
7677 }
7778
7879 /**
@@ -146,16 +147,17 @@ protected function normalizeValue(string $value): string
146147 *
147148 * @param object|string|float|int $value
148149 * @param int|null $scale Decimal places in the result. Omit to enable auto-detection.
150+ * @param bool $strict If scale should be strictly checked to avoid accidental precision loss.
149151 *
150152 * @return static
151153 */
152- public static function create (object |string |float |int $ value , ?int $ scale = null ): static
154+ public static function create (object |string |float |int $ value , ?int $ scale = null , bool $ strict = false ): static
153155 {
154156 if ($ scale === null && $ value instanceof static) {
155157 return clone $ value ;
156158 }
157159
158- return new static ($ value , $ scale );
160+ return new static ($ value , $ scale, $ strict );
159161 }
160162
161163 /**
@@ -737,7 +739,7 @@ protected function copy(?string $integerPart = null, ?string $decimalPart = null
737739 }
738740 if ($ decimalPart !== null ) {
739741 $ clone ->fractionalPart = $ decimalPart ;
740- $ clone ->setScale (null );
742+ $ clone ->setScale (null , false );
741743 }
742744 if ($ negative !== null ) {
743745 $ clone ->negative = $ negative ;
@@ -860,15 +862,16 @@ protected function fromScientific(string $value, ?int $scale): void
860862
861863 /**
862864 * @param int|null $scale
865+ * @param bool $strict
863866 *
864867 * @throws \InvalidArgumentException
865868 *
866869 * @return void
867870 */
868- protected function setScale (?int $ scale ): void
871+ protected function setScale (?int $ scale, bool $ strict ): void
869872 {
870873 $ calculatedScale = strlen ($ this ->fractionalPart );
871- if ($ scale && $ calculatedScale > $ scale ) {
874+ if ($ strict && $ scale && $ calculatedScale > $ scale ) {
872875 throw new InvalidArgumentException ('Loss of precision detected. Detected scale ` ' . $ calculatedScale . '` > ` ' . $ scale . '` as defined. ' );
873876 }
874877
0 commit comments