diff --git a/Eloquent/Concerns/HasAttributes.php b/Eloquent/Concerns/HasAttributes.php index d672f9ebb..2b1b7ca29 100644 --- a/Eloquent/Concerns/HasAttributes.php +++ b/Eloquent/Concerns/HasAttributes.php @@ -3,6 +3,9 @@ namespace Illuminate\Database\Eloquent\Concerns; use BackedEnum; +use Brick\Math\BigDecimal; +use Brick\Math\Exception\MathException as BrickMathException; +use Brick\Math\RoundingMode; use Carbon\CarbonImmutable; use Carbon\CarbonInterface; use DateTimeImmutable; @@ -23,6 +26,7 @@ use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Collection as BaseCollection; +use Illuminate\Support\Exceptions\MathException; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Date; use Illuminate\Support\Str; @@ -31,8 +35,6 @@ use ReflectionClass; use ReflectionMethod; use ReflectionNamedType; -use RuntimeException; -use TypeError; trait HasAttributes { @@ -1322,21 +1324,11 @@ public function fromFloat($value) */ protected function asDecimal($value, $decimals) { - if (extension_loaded('bcmath')) { - return bcadd($value, 0, $decimals); - } - - if (! is_numeric($value)) { - throw new TypeError('$value must be numeric.'); - } - - if (is_string($value) && Str::contains($value, 'e', true)) { - throw new RuntimeException('The "decimal" model cast is unable to handle string based floats with exponents.'); + try { + return (string) BigDecimal::of($value)->toScale($decimals, RoundingMode::HALF_UP); + } catch (BrickMathException $e) { + throw new MathException('Unable to cast value to a decimal.', previous: $e); } - - [$int, $fraction] = explode('.', $value) + [1 => '']; - - return Str::of($int)->padLeft('1', '0').'.'.Str::of($fraction)->limit($decimals, '')->padRight($decimals, '0'); } /**