Cldr v0.0.10 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
Functions
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(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 isdefault_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 DecimalFor 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>
Return the log10 of a number.
number
is an integer, a float or a DecimalFor integer and float it calls the BIF
:math.log10/1
function.- For
Decimal
,log10
is is rolled by hand using the identifylog10(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(%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_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>
Returns the number of decimal digits in the integer part of a number.
number
can be an integer, float orDecimal
.
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{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 zeroes from an integer.
number
must be an integer.
Examples
iex> Cldr.Number.Math.remove_trailing_zeros(1234000)
1234
Calculate the nth root of a number.
number
is an integer or a Decimalnth
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>
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 Decimaln
is the number of significant digits to which thenumber
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
Calculates the square root of a Decimal number using Newton’s method.
number
must be aDecimal
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>
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.
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