# View Source Cldr.Math(cldr_utils v2.27.0)

Math helper functions for number formatting.

# Summary

## Functions

Adds two numbers together.

Returns the adjusted modulus of `x` and `y`.

Returns a tuple representing a number in a normalized form with the mantissa in the range `0 < m < 10` and a base 10 exponent.

Returns a tuple representing a number in a normalized form with the mantissa in the range `0 < m < 10` and a base 10 exponent.

Returns the default number of rounding digits.

Returns the default rounding mode for rounding operations.

Divides one number by the other.

Returns the adjusted remainder and dividend of two integers.

Returns the remainder and dividend of two integers.

Return the log10 of a number.

Return the natural log of a number.

Calculates the modulo of a number (integer, float or Decimal).

Multiplies two numbers together.

Raises one number to an exponent.

Raises a number to a integer power.

Calculate the nth root of a number.

Round a number to an arbitrary precision using one of several rounding algorithms.

Rounds a number to a specified number of significant digits.

Calculates the square root of a Decimal number using Newton's method.

Subtracts one number from another.

Convert a Decimal to a float

Check if a `number` is within a `range`.

# Types

Link to this type

# normalised_decimal()

View Source
```@type normalised_decimal() ::
{%Decimal{coef: term(), exp: term(), sign: term()}, integer()}```
Link to this type

# number_or_decimal()

View Source
```@type number_or_decimal() ::
number() | %Decimal{coef: term(), exp: term(), sign: term()}```
Link to this type

# rounding()

View Source
```@type rounding() ::
:down | :half_up | :half_even | :ceiling | :floor | :half_down | :up```

# Functions

Link to this function

View Source (since 2.25.0)

Adds two numbers together.

The numbers can be integers, floats or Decimals. The type of the return will be Decimal if the either of the arguments is a Decimal.

If both arguments are integers, the result will be an integer. If either of the arguments is a float, the result will be a float.

Link to this function

# amod(x, y)

View Source
`@spec amod(number_or_decimal(), number_or_decimal()) :: number_or_decimal()`

Returns the adjusted modulus of `x` and `y`.

Link to this function

# coef_exponent(number)

View Source
`@spec coef_exponent(number_or_decimal()) :: {number_or_decimal(), integer()}`

Returns a tuple representing a number in a normalized form with the mantissa in the range `0 < m < 10` and a base 10 exponent.

• `number` is an integer, float or Decimal

## Examples

``````Cldr.Math.coef_exponent(Decimal.new(1.23004))
{Decimal.new("1.23004"), 0}

Cldr.Math.coef_exponent(Decimal.new(465))
{Decimal.new("4.65"), 2}

Cldr.Math.coef_exponent(Decimal.new(-46.543))
{Decimal.new("-4.6543"), 1}``````
Link to this function

# coef_exponent_digits(number)

View Source
`@spec coef_exponent_digits(number_or_decimal()) :: {Cldr.Digits.t(), integer()}`

Returns a tuple representing a number in a normalized form with the mantissa in the range `0 < m < 10` and a base 10 exponent.

The mantissa is represented as tuple of the form `Digits.t`.

• `number` is an integer, float or Decimal

## Examples

``````Cldr.Math.coef_exponent_digits(Decimal.new(1.23004))
{{[1, 2, 3, 0], 1, 1}, 0}

Cldr.Math.coef_exponent_digits(Decimal.new(465))
{{[4, 6, 5], 1, 1}, -1}

Cldr.Math.coef_exponent_digits(Decimal.new(-46.543))
{{[4, 6, 5, 4], 1, -1}, 1}``````
Link to this function

# default_rounding()

View Source
`@spec default_rounding() :: integer()`

Returns the default number of rounding digits.

Link to this function

# default_rounding_mode()

View Source
`@spec default_rounding_mode() :: atom()`

Returns the default rounding mode for rounding operations.

Link to this function

# div(num_1, num_2)

View Source (since 2.25.0)

Divides one number by the other.

The numbers can be integers, floats or Decimals. The type of the return will be Decimal if the either of the arguments is a Decimal.

If both arguments are numbers, the resulting type will be a be a Decimal.

Link to this function

# div_amod(int1, int2)

View Source
`@spec div_amod(integer(), integer()) :: {integer(), integer()}`

Returns the adjusted remainder and dividend of two integers.

This version will return the divisor if the remainder would otherwise be zero.

Link to this function

# div_mod(int1, int2)

View Source
`@spec div_mod(integer(), integer()) :: {integer(), integer()}`

Returns the remainder and dividend of two integers.

Link to this function

# log10(number)

View Source
`@spec log10(number_or_decimal()) :: number_or_decimal()`

Return the log10 of a number.

• `number` is an integer, a float or a Decimal

## Examples

``````iex> Cldr.Math.log10(100)
2.0

iex> Cldr.Math.log10(123)
2.089905111439398

iex> Cldr.Math.log10(Decimal.new(9000))
Decimal.new("3.953767554157656512064441441")``````
Link to this function

# log(number)

View Source

Return the natural log of a number.

• `number` is an integer, a float or a Decimal

• For integer and float it calls the BIF `:math.log10/1` function.

• For Decimal the log is rolled by hand.

## Examples

``````iex> Cldr.Math.log(123)
4.812184355372417

iex> Cldr.Math.log(Decimal.new(9000))
Decimal.new("9.103886231350952380952380952")``````
Link to this function

# maybe_integer(a)

View Source
Link to this function

# mod(number, modulus)

View Source
`@spec mod(number_or_decimal(), number_or_decimal()) :: number_or_decimal()`

Calculates the modulo of a number (integer, float or Decimal).

Note that this function uses `floored division` whereas the builtin `rem` function uses `truncated division`. See `Decimal.rem/2` if you want a `truncated division` function for Decimals that will return the same value as the BIF `rem/2` but in Decimal form.

See Wikipedia for an explanation of the difference.

## Examples

``````iex> Cldr.Math.mod(1234.0, 5)
4.0

iex> Cldr.Math.mod(Decimal.new("1234.456"), 5)
Decimal.new("4.456")

iex> Cldr.Math.mod(Decimal.new("123.456"), Decimal.new("3.4"))
Decimal.new("1.056")

iex> Cldr.Math.mod Decimal.new("123.456"), 3.4
Decimal.new("1.056")``````
Link to this function

# mult(num_1, num_2)

View Source (since 2.25.0)

Multiplies two numbers together.

The numbers can be integers, floats or Decimals. The type of the return will be Decimal if the either of the arguments is a Decimal.

If both arguments are integers, the result will be an integer. If either of the arguments is a float, the result will be a float.

Link to this function

# pow(n, m)

View Source

Raises one number to an exponent.

Link to this function

# power(number, n)

View Source
`@spec power(number_or_decimal(), number_or_decimal()) :: number_or_decimal()`

Raises a number to a integer power.

Raises a number to a power using the the binary method. There is one exception for Decimal numbers that raise `10` to some power. In this case the power is calculated by shifting the Decimal exponent which is quite efficient.

This function works only with integer exponents!

## Examples

``````iex> Cldr.Math.power(10, 2)
100

iex> Cldr.Math.power(10, 3)
1000

iex> Cldr.Math.power(10, 4)
10000

iex> Cldr.Math.power(2, 10)
1024``````
Link to this function

# root(number, nth)

View Source

Calculate the nth root of a number.

• `number` is an integer or a Decimal

• `nth` is a positive integer

## Examples

``````iex> Cldr.Math.root Decimal.new(8), 3
Decimal.new("2.0")

iex> Cldr.Math.root Decimal.new(16), 4
Decimal.new("2.0")

iex> Cldr.Math.root Decimal.new(27), 3
Decimal.new("3.0")``````
Link to this function

# round(number, places \\ 0, mode \\ :half_even)

View Source

Round a number to an arbitrary precision using one of several rounding algorithms.

Rounding algorithms are based on the definitions given in IEEE 754, but also include 2 additional options (effectively the complementary versions):

## Arguments

• `number` is a `float`, `integer` or `Decimal`

• `places` is an integer number of places to round to

• `mode` is the rounding mode to be applied. The default is `:half_even`

## Rounding algorithms

Directed roundings:

• `:down` - Round towards 0 (truncate), eg 10.9 rounds to 10.0

• `:up` - Round away from 0, eg 10.1 rounds to 11.0. (Non IEEE algorithm)

• `:ceiling` - Round toward +∞ - Also known as rounding up or ceiling

• `:floor` - Round toward -∞ - Also known as rounding down or floor

Round to nearest:

• `:half_even` - Round to nearest value, but in a tiebreak, round towards the nearest value with an even (zero) least significant bit, which occurs 50% of the time. This is the default for IEEE binary floating-point and the recommended value for decimal.

• `:half_up` - Round to nearest value, but in a tiebreak, round away from 0. This is the default algorithm for Erlang's Kernel.round/2

• `:half_down` - Round to nearest value, but in a tiebreak, round towards 0 (Non IEEE algorithm)

## Notes

Link to this function

# round_significant(number, n)

View Source
`@spec round_significant(number_or_decimal(), integer()) :: number_or_decimal()`

Rounds a number to a specified number of significant digits.

This is not the same as rounding fractional digits which is performed by `Decimal.round/2` and `Float.round`

• `number` is a float, integer or Decimal

• `n` is the number of significant digits to which the `number` should be rounded

## Examples

``````iex> Cldr.Math.round_significant(3.14159, 3)
3.14

iex> Cldr.Math.round_significant(10.3554, 1)
10.0

iex> Cldr.Math.round_significant(0.00035, 1)
0.0004

iex> Cldr.Math.round_significant(Decimal.from_float(3.342742283480345e27), 7)
Decimal.new("3.342742E+27")``````

## Notes about precision

Since floats cannot accurately represent all decimal numbers, so rounding to significant digits for a float cannot always return the expected results. For example:

``````=> Cldr.Math.round_significant(3.342742283480345e27, 7)
Expected result:  3.342742e27
Actual result: 3.3427420000000003e27``````

Use of `Decimal` numbers avoids this issue:

``````=> Cldr.Math.round_significant(Decimal.from_float(3.342742283480345e27), 7)
Expected result:  #Decimal<3.342742E+27>
Actual result: #Decimal<3.342742E+27>``````

## More on significant digits

• 3.14159 has six significant digits (all the numbers give you useful information)

• 1000 has one significant digit (only the 1 is interesting; you don't know anything for sure about the hundreds, tens, or units places; the zeroes may just be placeholders; they may have rounded something off to get this value)

• 1000.0 has five significant digits (the ".0" tells us something interesting about the presumed accuracy of the measurement being made: that the measurement is accurate to the tenths place, but that there happen to be zero tenths)

• 0.00035 has two significant digits (only the 3 and 5 tell us something; the other zeroes are placeholders, only providing information about relative size)

• 0.000350 has three significant digits (that last zero tells us that the measurement was made accurate to that last digit, which just happened to have a value of zero)

• 1006 has four significant digits (the 1 and 6 are interesting, and we have to count the zeroes, because they're between the two interesting numbers)

• 560 has two significant digits (the last zero is just a placeholder)

• 560.0 has four significant digits (the zero in the tenths place means that the measurement was made accurate to the tenths place, and that there just happen to be zero tenths; the 5 and 6 give useful information, and the other zero is between significant digits, and must therefore also be counted)

Many thanks to Stackoverflow

Link to this function

# sqrt(number, precision \\ 0.0001)

View Source

Calculates the square root of a Decimal number using Newton's method.

• `number` is an integer, float or Decimal. For integer and float, `sqrt` is delegated to the erlang `:math` module.

We convert the Decimal to a float and take its `:math.sqrt` only to get an initial estimate. The means typically we are only two iterations from a solution so the slight hack improves performance without sacrificing precision.

## Examples

``````iex> Cldr.Math.sqrt(Decimal.new(9))
Decimal.new("3.0")

iex> Cldr.Math.sqrt(Decimal.new("9.869"))
Decimal.new("3.141496458696078173887197038")``````
Link to this function

# sub(num_1, num_2)

View Source (since 2.25.0)

Subtracts one number from another.

The numbers can be integers, floats or Decimals. The type of the return will be Decimal if the either of the arguments is a Decimal.

If both arguments are integers, the result will be an integer. If either of the arguments is a float, the result will be a float.

Link to this function

# to_float(decimal)

View Source
`@spec to_float(%Decimal{coef: term(), exp: term(), sign: term()}) :: float()`

Convert a Decimal to a float

• `decimal` must be a Decimal

This is very likely to lose precision - lots of numbers won't make the round trip conversion. Use with care. Actually, better not to use it at all.

Link to this function

# within(number, range)

View Source
`@spec within(number(), integer() | Range.t()) :: boolean()`

Check if a `number` is within a `range`.

• `number` is either an integer or a float.

When an integer, the comparison is made using the standard Elixir `in` operator.

When `number` is a float the comparison is made using the `>=` and `<=` operators on the range endpoints. Note the comparison for a float is only for floats that have no fractional part. If a float has a fractional part then `within` returns `false`.

Since this function is only provided to support plural rules, the float comparison is only useful if the float has no fractional part.

## Examples

``````iex> Cldr.Math.within(2.0, 1..3)
true

iex> Cldr.Math.within(2.1, 1..3)
false``````