# `NumberF.Precision`
[🔗](https://github.com/jamesnjovu/elixir_number_functions/blob/v0.3.0/lib/number_f/precision.ex#L1)

Functions for handling numerical precision issues and implementing various rounding strategies.

# `approximately_equal`

Checks if two floating point numbers are approximately equal.

## Parameters
  - `a`: First number
  - `b`: Second number
  - `epsilon`: Maximum allowed difference (default: 1.0e-10)

## Examples

    iex> NumberF.Precision.approximately_equal(0.1 + 0.2, 0.3)
    true

    iex> NumberF.Precision.approximately_equal(0.1, 0.2)
    false

# `bankers_round`

Rounds a number using banker's rounding (round to even).
This is more statistically unbiased than standard rounding.

## Parameters
  - `number`: The number to round
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.bankers_round(2.5, 0)
    2.0

    iex> NumberF.Precision.bankers_round(3.5, 0)
    4.0

    iex> NumberF.Precision.bankers_round(2.125, 2)
    2.12

    iex> NumberF.Precision.bankers_round(2.135, 2)
    2.14

# `ceiling`

Rounds a number up to a specified precision (ceiling).

## Parameters
  - `number`: The number to round
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.ceiling(3.14159, 2)
    3.15

    iex> NumberF.Precision.ceiling(3.14159, 1)
    3.2

# `clamp`

Constrains a value to a range.

The single most reached-for utility that was missing.

## Examples

    iex> NumberF.Precision.clamp(15, 0, 10)
    10

    iex> NumberF.Precision.clamp(-5, 0, 10)
    0

    iex> NumberF.Precision.clamp(5, 0, 10)
    5

# `custom_round`

Implements a custom rounding function with different modes.

## Parameters
  - `number`: The number to round
  - `precision`: Number of decimal places
  - `mode`: Rounding mode (default: :half_up)
    - :half_up - Round to nearest, 0.5 rounds up (standard)
    - :half_down - Round to nearest, 0.5 rounds down
    - :half_even - Round to nearest, 0.5 rounds to even (banker's)
    - :ceiling - Always round up
    - :floor - Always round down
    - :truncate - Always truncate (toward zero)

## Examples

    iex> NumberF.Precision.custom_round(2.5, 0, :half_up)
    3.0

    iex> NumberF.Precision.custom_round(2.5, 0, :half_down)
    2.0

    iex> NumberF.Precision.custom_round(2.5, 0, :half_even)
    2.0

    iex> NumberF.Precision.custom_round(3.5, 0, :half_even)
    4.0

# `floor`

Rounds a number down to a specified precision (floor).

## Parameters
  - `number`: The number to round
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.floor(3.14159, 2)
    3.14

    iex> NumberF.Precision.floor(3.14159, 1)
    3.1

# `precise_format`

Formats a number with a specified precision, using string manipulation
to avoid floating-point rounding issues.

## Parameters
  - `number`: The number to format
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.precise_format(3.14159, 2)
    "3.14"

    iex> NumberF.Precision.precise_format(3.14159, 4)
    "3.1416"

# `round_half_away_from_zero`

Rounds half away from zero.

## Precision

This is the rounding most people mean by "round half up", and it differs from
Elixir's `round/1` for negatives: `round(-2.5)` is `-3` in Elixir but many
languages return `-2`. It also differs from `bankers_round/2`, which rounds
half to even to avoid systematic bias. Use this for presentation and
`bankers_round/2` for money that accumulates.

## Examples

    iex> NumberF.Precision.round_half_away_from_zero(2.5, 0)
    3.0

    iex> NumberF.Precision.round_half_away_from_zero(-2.5, 0)
    -3.0

# `round_half_even`

Rounds half to even. An alias for `bankers_round/2`, named for discoverability.

## Examples

    iex> NumberF.Precision.round_half_even(2.5, 0)
    2.0

    iex> NumberF.Precision.round_half_even(3.5, 0)
    4.0

# `round_to`

Rounds a number to a specific increment.

## Parameters
  - `number`: The number to round
  - `increment`: The increment to round to (default: 1.0)
  - `strategy`: The rounding strategy (:nearest, :up, :down, or :bankers)

## Examples

    iex> NumberF.Precision.round_to(3.14159, 0.05, :nearest)
    3.15

    iex> NumberF.Precision.round_to(3.14159, 0.1, :up)
    3.2

    iex> NumberF.Precision.round_to(3.14159, 0.1, :down)
    3.1

# `round_with_precision`

Rounds a number to a specified number of decimal places.

## Parameters
  - `number`: The number to round
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.round_with_precision(3.14159, 2)
    3.14

    iex> NumberF.Precision.round_with_precision(3.14159, 4)
    3.1416

# `safe_divide`

Divides, returning `default` instead of raising when the denominator is zero.

## Edge cases

Use this at boundaries where a zero denominator is expected and meaningful —
a rate over an empty period, for instance. Where zero indicates a bug, let the
division raise instead of hiding it behind a default.

## Examples

    iex> NumberF.Precision.safe_divide(10, 4)
    2.5

    iex> NumberF.Precision.safe_divide(10, 0)
    0.0

    iex> NumberF.Precision.safe_divide(10, 0, :infinity)
    :infinity

# `sanitize_float`

Sanitizes a float value to handle special cases like NaN and Infinity.

## Parameters
  - `value`: The value to sanitize
  - `default`: Default value to return for invalid numbers (default: 0.0)

## Examples

    iex> NumberF.Precision.sanitize_float(:nan, 0.0)
    0.0

    iex> NumberF.Precision.sanitize_float(:infinity, 0.0)
    0.0

    iex> NumberF.Precision.sanitize_float(3.14, 0.0)
    3.14

# `sign`

Returns -1, 0 or 1 according to the sign of the number.

## Examples

    iex> NumberF.Precision.sign(-4.2)
    -1

    iex> NumberF.Precision.sign(0)
    0

    iex> NumberF.Precision.sign(17)
    1

# `truncate`

Truncates a number to a specified precision (cuts off digits).

## Parameters
  - `number`: The number to truncate
  - `precision`: Number of decimal places (default: 2)

## Examples

    iex> NumberF.Precision.truncate(3.14159, 2)
    3.14

    iex> NumberF.Precision.truncate(-3.14159, 2)
    -3.14

---

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