Cldr v0.0.12 Cldr.Number.Math

Math helper functions for number formatting

Summary

Functions

Returns the default rounding used by Cldr

Returns the fractional part of a float or Decimal as an integer

Return the natural log of a number

Return the log10 of a number

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

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

Returns the number of decimal digits in the integer part of a number

Returns the number of leading zeros in a Decimal fraction

Raises a number to a integer power

Remove trailing zeroes from an integer

Calculate the nth root of a number

Rounds a number to a specified number of significant digits

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

Convert a Decimal to a float

Check if a number is within a range

Types

normalised_decimal()
normalised_decimal() :: {%Decimal{coef: term, exp: term, sign: term}, integer}
number_or_decimal()
number_or_decimal ::
  number |
  %Decimal{coef: term, exp: term, sign: term}

Functions

default_rounding()
default_rounding() :: integer

Returns the default rounding used by Cldr.

This function is used to control fraction_as_integer/2 and any other Cldr function that takes a rounding argument.

fraction_as_integer(fraction, rounding \\ 3)
fraction_as_integer(number_or_decimal, integer) :: integer

Returns the fractional part of a float or Decimal as an integer.

  • number can be either a float, Decimal or integer although an integer has no fraction part and will therefore always return 0.

  • rounding is the precision applied on each internal iteration as the fraction is converted to an integer. The default rounding is default_rounding().

Examples

iex> Cldr.Number.Math.fraction_as_integer(123.456)
456

iex> Cldr.Number.Math.fraction_as_integer(123.456, 2)
46

iex> Cldr.Number.Math.fraction_as_integer(Decimal.new("123.456"), 3)
456

iex> Cldr.Number.Math.fraction_as_integer(1999, 3)
0

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.Number.Math.log(123)
4.812184355372417

iex> Cldr.Number.Math.log(Decimal.new(9000))
#Decimal<9.103886231350952380952380952>
log10(number)

Return the log10 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, log10 is is rolled by hand using the identify log10(x) = ln(x) / ln(10)

Examples

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

iex> Cldr.Number.Math.log10(123)
2.089905111439398

iex> Cldr.Number.Math.log10(Decimal.new(9000))
#Decimal<3.953767554157656512064441441>
mantissa_exponent(number)
mantissa_exponent(%Decimal{coef: term, exp: term, sign: term}) :: normalised_decimal

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

  • number must be a Decimal

Examples

Cldr.Number.Math.mantissa_exponent(Decimal.new(1.23004))
{#Decimal<1.23004>, 0}

Cldr.Number.Math.mantissa_exponent(Decimal.new(465))
{#Decimal<4.65>, 2}

Cldr.Number.Math.mantissa_exponent(Decimal.new(-46.543))
{#Decimal<-4.6543>, 1}
mod(number, modulus)
mod(number_or_decimal, number_or_decimal) ::
  float |
  %Decimal{coef: term, exp: term, sign: term}

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.Number.Math.mod(1234.0, 5)
4.0

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

iex> Cldr.Number.Math.mod(Decimal.new(123.456), Decimal.new(3.4))
#Decimal<1.056>

iex> Cldr.Number.Math.mod Decimal.new(123.456), 3.4
#Decimal<1.056>
number_of_integer_digits(number)
number_of_integer_digits(number_or_decimal) :: integer

Returns the number of decimal digits in the integer part of a number.

  • number can be an integer, float or Decimal.

Examples

iex(10)> Cldr.Number.Math.number_of_integer_digits(1234)
4

iex(11)> Cldr.Number.Math.number_of_integer_digits(Decimal.new("123456789"))
9

iex(15)> Cldr.Number.Math.number_of_integer_digits(1234.456)
4
number_of_leading_zeros(decimal)
number_of_leading_zeros(%Decimal{coef: term, exp: term, sign: term}) :: integer

Returns the number of leading zeros in a Decimal fraction.

  • number is any Decimal number

Returns the number of leading zeros in a Decimal number that is between -1..1 (ie, has no integer part). If the number is outside -1..1 it retuns a negative number, the abs value of which is the number of integer digits in the number.

Examples

iex> Cldr.Number.Math.number_of_leading_zeros(Decimal.new(0.0001))
3

iex> Cldr.Number.Math.number_of_leading_zeros(Decimal.new(3.0001))
-1

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.

For further reading see this article

This function works only with integer exponents!

Examples

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

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

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

iex> Cldr.Number.Math.power(2, 10)
1024
remove_trailing_zeros(number)
remove_trailing_zeros(integer) :: integer

Remove trailing zeroes from an integer.

  • number must be an integer.

Examples

iex> Cldr.Number.Math.remove_trailing_zeros(1234000)
1234
root(number, nth)

Calculate the nth root of a number.

  • number is an integer or a Decimal

  • nth is a positive integer

Examples

iex> Cldr.Number.Math.root Decimal.new(8), 3
#Decimal<2.0>

iex> Cldr.Number.Math.root Decimal.new(16), 4
#Decimal<2.0>

iex> Cldr.Number.Math.root Decimal.new(27), 3
#Decimal<3.0>
round_significant(number, n)
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 decimals which is performed by Decimal.round/2.

  • number is a float, integer or Decimal

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

Examples

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

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

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

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

sqrt(number, precision \\ 0.0001)

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

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.Number.Math.sqrt(Decimal.new(9))
#Decimal<3.0>

iex> Cldr.Number.Math.sqrt(Decimal.new(9.869))
#Decimal<3.141496458696078173887197038>
to_float(decimal)
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.

within(number, range)
within(number, integer) :: 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.Number.Math.within(2.0, 1..3)
true

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