HowTo: Integrate and use precise decimal numbers

Edit on GitHub

The document shows how to install and work with precise decimal objects.

The decimal-object library lets you work with precise decimal numbers. A decimal number is a number that is smaller than an integer. Decimal numbers can be used when more precision is required, while float numbers are imprecise and shouldn’t be used for cases where exact precision is necessary. For example, when dealing with money (a price of a product), measuring weights or liquids (food or water respectively), and length (meters such as a cable), decimal numbers can be used.

Why to use decimal objects

The benefits of using decimal numbers are as follows:

  • Managing long and short accurate values as needed.
  • Supporting arithmetic, comparing, rounding, and casting operations.
  • Representing objects instead of strings.
  • Supporting exponential representation of the value.
  • Being immutable: the operations construct a new decimal value, and the value of the original decimal stays unchangeable.

Installation

To install the {{decimal-object}} library, you can use Composer. For more information, see Decimal Object on GitHub.

How decimal numbers work with transfer objects

You can specify Decimal as a type of your Data Transfer Object’s property. To define it, use the decimal type:

<transfer name="StockProduct">
    <property name="quantity" type="decimal"/>
</transfer>

For more information about working with Data Transfer Objects, see Create, use, and extend the transfer objects.

Create a decimal value object

Decimal objects can be created using one of the following types: int, numeric string (including numbers in exponential representation), float, objects that have the __toString() method defined and returning a numeric string, for example:

$decimal = new Decimal(7);
$decimal = new Decimal(3.14);
$decimal = new Decimal('2.718');
$decimal = new Decimal('-.3');
$decimal = new Decimal('6.22e8');

Decimals are immutable. This means that arithmetic operations with decimals return a new decimal object without impacting the original decimal object. Thus, the result of a decimal operation is always a new decimal.

Use a decimal value object in arithmetic, comparing, casting, and rounding operations

Decimal objects can use decimal objects, plain integers, and string values. They support not only arithmetic operations but also can be used with comparing, casting, and rounding methods. The following section provides an explanation of each of them with some examples.

Basic arithmetic operations

They always return a new Decimal object using the maximum precision of the object. The following are examples of using Decimal objects with different arithmetic methods:

  1. add(): Returns the sum of the decimal and the given value.
$decimal = new Decimal(5);
$decimal = $decimal->add(5); //10

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$decimal = $decimalOne->add($decimalTwo); //5.858
  1. subtract(): Returns the subtraction of the decimal and given values.
$decimal = new Decimal(5);
$decimal = $decimal->subtract(5); //0

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$decimal = $decimalOne->subtract($decimalTwo); //-0.422
  1. multiply(): Returns the multiplication of the decimal value by the given value.
$decimal = new Decimal(5);
$decimal = $decimal->multiply(5); //25

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$decimal = $decimalOne->multiply($decimalTwo); //8.53452
  1. divide(): Returns the division of the decimal value by the given value.
$decimal = new Decimal(5);
$decimal = $decimal->divide(5, 3); //1.000

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$decimal = $decimalOne->divide($decimalTwo, 3); //0.865
  1. sqrt(): Extracts the square root of a decimal value.
$decimal = new Decimal(144);
$decimal = $decimal->sqrt(); //12
  1. pow(): Raises a decimal value to power.
$decimal = new Decimal(3);
$decimal = $decimal->pow(3); //27
  1. absolute(): Returns the absolute value of a number.
$decimal = new Decimal(-17);
$decimal = $decimal->absolute(3); //17
  1. mod(): Returns the remainder of a division of any number type of the original decimal by another number type of the given decimal.
$decimal = new Decimal(7);
$decimal = $decimal->mod(2); //1
  1. negate(): Returns a negative value of the decimal value.
$decimal = new Decimal(7);
$decimal = $decimal->negate(); //-7

Table of exceptions

The table provides additional information about exceptions that may occur when working with decimal objects.

METHOD EXCEPTION DESCRIPTION
add(), subtract(), multiply(), divide(), mod() InvalidArgumentException Thrown if the given value is not a decimal, float, string, or integer.
divide() DivisionByZeroError Thrown if dividing by 0.

Compare operations

Decimal objects can be compared to the given values to check the equal or relative ordering of these values. You can determine whether the new decimal is positive or negative, equal or greater/less than a specified one.

  1. equals(): Returns true if the decimal value equals the specified value; otherwise, false.
$decimal = new Decimal(5);
$isEquals = $decimal->equals(5); //true

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$isEquals = $decimalOne->equals($decimalTwo); //false
  1. isPositive(): Returns true if the decimal value is positive; otherwise false.
$decimal = new Decimal(5);
$isPositive = $decimal->isPositive(); //true
  1. isNegative(): Returns true if the decimal value is negative; otherwise false.
$decimal = new Decimal(5);
$isNegative = $decimal->isNegative(); //false
  1. greaterThan(): Returns true if the decimal value is greater than the given value; otherwise false.
$decimal = new Decimal(5);
$isGreater = $decimal->greaterThan(5); //false

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$isGreater = $decimalOne->greaterThan($decimalTwo); //false
  1. greaterThanOrEquals(): Returns true if the decimal value is greater or equals the given value; otherwise false.
$decimal = new Decimal(5);
$isGreatherOrEquals = $decimal->greatherThanOrEquals(5); //true

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$isGreatherOrEquals = $decimalOne->greatherThanOrEquals($decimalTwo); //false
  1. lessThan(): Returns true if the decimal value is less than the given value; otherwise false.
$decimal = new Decimal(5);
$isLess = $decimal->lessThan(5); //false

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$isLess = $decimalOne->lessThan($decimalTwo); //true
  1. lessThanOrEquals(): Returns true if the decimal value is less or equals the given value; otherwise false.
$decimal = new Decimal(5);
$isLessOrEquals = $decimal->lessThanOrEquals(5); //true

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$isLessOrEquals = $decimalOne->lessThanOrEquals($decimalTwo); //true
  1. compareTo(): Returns the following:
  • -1 if the decimal value is less than $value
  • 0 if the decimal value is equal to $value
  • 1 if the decimal value is greater than $value.

where $value is the value being transferred in the method.

$decimal = new Decimal(5);
$result = $decimal->compareTo(5); //0

$decimalOne = new Decimal(2.718);
$decimalTwo = new Decimal(3.14);
$result = $decimalOne->compareTo($decimalTwo); //-1

Round operations

The rounding operations return a new decimal object value that rounds up or down to the original decimal value. The following methods can be used in the rounding mode for decimal objects:

  1. round(): Returns a rounded version of the given decimal value.
Note

Rounds follow the rules of mathematics.

$decimal = new Decimal(2.718);
$decimal = $decimal->round(2.718); //3
  1. floor(): Rounds the fractions of a decimal value down to the closest integer.
$decimal = new Decimal(2.718);
$decimal = $decimal->floor(2.718); //2
  1. ceil(): Rounds fractions of a decimal value up to the closest integer.
$decimal = new Decimal(2.718);
$decimal = $decimal->ceil(2.718); //3
  1. truncate(): Discards all digits behind the defined decimal point.
$decimal = new Decimal(2.718);
$decimal = $decimal->truncate(2); //2.71

Table of exceptions

The table provides additional information about the exception that may be thrown when working with decimal objects in rounding operations.

METHOD EXCEPTION DESCRIPTION
truncate() InvalidArgumentException Thrown if the given scale is less than or equal to 0.

Cast operations

The casting operations convert decimal objects into simple data types: integer, float, or string using the following methods:

  1. toFloat(): Casts a decimal value to a float.
$decimal = new Decimal(3.14);
$float = $decimal->toFloat(); //3.14
  1. toInt(): Casts a decimal value to an integer.
$decimal = new Decimal(3.14);
$integer = $decimal->toInt(); //3
  1. toString(): Casts a decimal value to a string.
$decimal = new Decimal(3.14);
$string = $decimal->toString(); //"3.14"
  1. toScientific(): Returns an exponential representation of the number.
$decimal = new Decimal(3.14);
$string = $decimal->toScientific(); //"3.14e0"
  1. trim(): Trims trailing zeroes.
$decimal = new Decimal(3.1400000);
$decimal = $decimal->trim(); //3.14

Table of exceptions

The table provides additional information about exceptions that may be thrown when working with decimal objects in casting operations.

METHOD EXCEPTION DESCRIPTION
toInt() TypeError Thrown if the integral part of the value is greater than PHP_INT_MAX or less than PHP_INT_MIN.
toFloat() TypeError Thrown if the integral or fractional part of the value is greater than PHP_INT_MAX or less than PHP_INT_MIN.