# `Localize.Utils.Digits`
[🔗](https://github.com/elixir-localize/localize/blob/v0.39.0/lib/localize/utils/digits.ex#L1)

Abstract representation of number (integer, float, Decimal) in tuple form
and functions for transformations on number parts.

Representing a number as a list of its digits, an integer representing
where the decimal point is placed, and an integer representing the sign
of the number allow more efficient transforms on the various parts of
the number as happens during the formatting of a number for string output.

A number in integer, float or Decimal form can be converted
to digit form with `to_digits/1`.

The digits can be converted back to normal form with
`Localize.Utils.Digits.to_integer/1`, `Localize.Utils.Digits.to_float/1`
and `Localize.Utils.Digits.to_decimal/1`.

# `t`

```elixir
@type t() :: {[0..9, ...], non_neg_integer(), 1 | -1}
```

Defines a number in a tuple form of three parts:

* A list of digits (0..9) representing the number.

* A digit representing the place of the decimal point
in the number.

* A `1` or `-1` representing the sign of the number.

# `fraction_as_integer`

```elixir
@spec fraction_as_integer(number() | Decimal.t() | {list(), list(), 1 | -1}) ::
  integer()
```

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

### Arguments

* `number` is a float, Decimal, integer, or a tuple of the form
  `{integer_list, fraction_list, sign}` as returned by `to_tuple/1`.

### Returns

* An integer representing the fractional digits.

### Examples

    iex> Localize.Utils.Digits.fraction_as_integer(123.456)
    456

    iex> Localize.Utils.Digits.fraction_as_integer(Decimal.new("123.456"))
    456

    iex> Localize.Utils.Digits.fraction_as_integer(1999)
    0

# `fraction_as_integer`

```elixir
@spec fraction_as_integer(float(), pos_integer()) :: integer()
```

Returns the fractional part of a float as an integer,
rounding to the specified number of digits first.

### Arguments

* `number` is a float.

* `rounding` is a positive integer specifying the number of
  fractional digits.

### Returns

* An integer representing the fractional digits.

### Examples

    iex> Localize.Utils.Digits.fraction_as_integer(1.456, 3)
    456

# `number_of_digits`

```elixir
@spec number_of_digits(
  number()
  | Decimal.t()
  | list()
  | {[integer(), ...], integer() | [integer(), ...], -1 | 1}
) :: integer()
```

Returns the number of decimal digits in a number
(integer, float, Decimal).

### Arguments

* `number` is an integer, float, `Decimal`,
  or a list (which is assumed to contain digits).

### Returns

* An integer count of the total number of digits.

### Examples

    iex> Localize.Utils.Digits.number_of_digits(1234)
    4

    iex> Localize.Utils.Digits.number_of_digits(Decimal.new("123456789"))
    9

    iex> Localize.Utils.Digits.number_of_digits(1234.456)
    7

    iex> Localize.Utils.Digits.number_of_digits(1234.56789098765)
    15

    iex> Localize.Utils.Digits.number_of_digits(~c"12345")
    5

# `number_of_integer_digits`

```elixir
@spec number_of_integer_digits(
  number()
  | Decimal.t()
  | list()
  | {[integer(), ...], integer() | [integer(), ...], -1 | 1}
) :: integer()
```

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

### Arguments

* `number` is an integer, float, `Decimal`, or
  a list (which is assumed to contain digits).

### Returns

* A non-negative integer count of integer digits.

### Examples

    iex> Localize.Utils.Digits.number_of_integer_digits(1234)
    4

    iex> Localize.Utils.Digits.number_of_integer_digits(Decimal.new("123456789"))
    9

    iex> Localize.Utils.Digits.number_of_integer_digits(1234.456)
    4

    iex> Localize.Utils.Digits.number_of_integer_digits(~c"12345")
    5

# `number_of_leading_zeros`

```elixir
@spec number_of_leading_zeros(number() | Decimal.t() | [integer(), ...]) :: integer()
```

Returns the number of leading zeros in the fractional
part of a number.

### Arguments

* `number` is an integer, float, Decimal, or a list of digits.

### Returns

* An integer count of leading zeros.

### Examples

    iex> Localize.Utils.Digits.number_of_leading_zeros(Decimal.new("0.0001"))
    3

# `number_of_trailing_zeros`

Returns the number of trailing zeros in an
integer number.

### Arguments

* `number` is an integer or a list of digits.

### Returns

* An integer count of trailing zeros.

### Examples

    iex> Localize.Utils.Digits.number_of_trailing_zeros(123000)
    3

# `remove_trailing_zeros`

```elixir
@spec remove_trailing_zeros(number() | Decimal.t() | [integer(), ...]) ::
  number() | [integer()]
```

Removes trailing zeros from the integer part of a number
and returns the integer part without trailing zeros.

### Arguments

* `number` is an integer, float, Decimal, or a list of digits.

### Returns

* An integer with trailing zeros removed, or a list with
  trailing zeros removed.

### Examples

    iex> Localize.Utils.Digits.remove_trailing_zeros(1234000)
    1234

    iex> Localize.Utils.Digits.remove_trailing_zeros(0)
    0

# `to_decimal`

Converts a digit tuple to a Decimal.

### Arguments

* `digits` is a tuple `{digit_list, place, sign}` as returned by `to_digits/1`.

### Returns

* A `%Decimal{}` struct.

### Examples

    iex> Localize.Utils.Digits.to_decimal({[1, 2, 3], 2, 1})
    Decimal.new("12.3")

# `to_digits`

Computes a list of the digits of the given IEEE 754 floating point number,
together with the location of the decimal point as `{digits, place, sign}`.

Given an IEEE 754 float, computes the shortest, correctly rounded list of
digits that converts back to the same Double value when read back with
`String.to_float/1`.  Implements the algorithm from "Printing Floating-Point
Numbers Quickly and Accurately" in Proceedings of the SIGPLAN '96 Conference
on Programming Language Design and Implementation.

A "compact" representation is returned, so there may be fewer digits returned
than the decimal point location.

### Arguments

* `number` is a float, integer, or Decimal.

### Returns

* A tuple `{digits, place, sign}` where `digits` is a list of integers
  0..9, `place` is the decimal point position, and `sign` is `1` or `-1`.

### Examples

    iex> Localize.Utils.Digits.to_digits(0.0)
    {[0], 1, 1}

    iex> Localize.Utils.Digits.to_digits(123)
    {[1, 2, 3], 3, 1}

# `to_float`

Converts a digit tuple to a float.

### Arguments

* `digits` is a tuple `{digit_list, place, sign}` as returned by `to_digits/1`.

### Returns

* A float.

### Examples

    iex> Localize.Utils.Digits.to_float({[1, 2, 3, 4], 2, 1})
    12.34

# `to_integer`

Converts a digit tuple to an integer.

### Arguments

* `digits` is a tuple `{digit_list, place, sign}` as returned by `to_digits/1`.

### Returns

* An integer.

### Examples

    iex> Localize.Utils.Digits.to_integer({[1, 2, 3, 4], 4, 1})
    1234

# `to_number`

Takes a list of digits and converts them back to a number of the same
type as `number`.

### Arguments

* `digits` is a tuple `{digit_list, place, sign}` as returned by `to_digits/1`.

* `number` is a number or atom indicating the desired return type.
  Supported values are an integer, float, `%Decimal{}`, or the atoms
  `:integer`, `:float`, `:decimal`.

### Returns

* A number of the requested type.

### Examples

    iex> Localize.Utils.Digits.to_number({[1, 2, 3], 3, 1}, :integer)
    123

    iex> Localize.Utils.Digits.to_number({[1, 2, 3], 3, 1}, :float)
    123.0

# `to_tuple`

```elixir
@spec to_tuple(Decimal.t() | number()) :: {list(), list(), integer()}
```

Converts given number to a list representation.

Given an IEEE 754 float, computes the shortest, correctly rounded list of
digits that converts back to the same Double value when read back with
`String.to_float/1`.  Implements the algorithm from "Printing Floating-Point
Numbers Quickly and Accurately" in Proceedings of the SIGPLAN '96 Conference
on Programming Language Design and Implementation.

Returns a tuple comprising a list for the integer part,
a list for the fractional part, and an integer for the sign.

### Arguments

* `number` is a float, integer, or Decimal.

### Returns

* A tuple `{integer_digits, fraction_digits, sign}` where each digit
  list contains integers 0..9 and `sign` is `1` or `-1`.

### Examples

    iex> Localize.Utils.Digits.to_tuple(123.456)
    {[1, 2, 3], [4, 5, 6], 1}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
