Decimal128
On this page
Overview
MongoDB 3.4 introduced support for a Decimal128 BSON type, which is a 128-bit decimal-based floating-point value capable of emulating decimal rounding with exact precision. This functionality is intended for applications that handle monetary data, such as financial and tax computations.
The MongoDB\BSON\Decimal128 class may be used to work with this type in PHP.
Working with Decimal128 Values
Inserting a Decimal128
The following example inserts a value of type Decimal128
into the price
field of a collection named inventory
:
$collection = (new MongoDB\Client)->test->inventory; $collection->insertOne([ '_id' => 1, 'item' => '26-inch monitor', 'price' => new MongoDB\BSON\Decimal128('428.79'), ]); $item = $collection->findOne(['_id' => 1]); var_dump($item);
The output would then resemble:
object(MongoDB\Model\BSONDocument)#9 (1) { ["storage":"ArrayObject":private]=> array(3) { ["_id"]=> int(1) ["item"]=> string(15) "26-inch monitor" ["price"]=> object(MongoDB\BSON\Decimal128)#13 (1) { ["dec"]=> string(6) "428.79" } } }
Mathematical Operations with BCMath
The extension does not provide any functionality for working
with Decimal128
values; however, the string representation of a
MongoDB\BSON\Decimal128 object may be used
with PHP's BCMath extension.
The following example adds two Decimal128
values and creates a new
Decimal128
value with the result from bcadd():
$lhs = new MongoDB\BSON\Decimal128('1.234'); $rhs = new MongoDB\BSON\Decimal128('5.678'); $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs)); var_dump($sum);
The output would then resemble:
object(MongoDB\BSON\Decimal128)#4 (1) { ["dec"]=> string(1) "6" }
This does not match the expected result of "6.912". Each operation in the BCMath API uses a scale to determine the number of decimal digits in the result. The default scale is zero, which is why the above example produces a result with no decimal precision.
In the following example, we use a scale of three for bcadd() to obtain the expected result:
$lhs = new MongoDB\BSON\Decimal128('1.234'); $rhs = new MongoDB\BSON\Decimal128('5.678'); $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs, 3)); var_dump($sum);
The output would then resemble:
object(MongoDB\BSON\Decimal128)#4 (1) { ["dec"]=> string(5) "6.912" }
In lieu of specifying a scale for each operation, a default scale may be set via
bcscale() or the bcmath.scale INI setting. The Decimal128
type
supports up to 34 decimal digits (i.e. significant digits).