MartinSStewart / elm-safe-int / SafeInt.Unchecked

Unchecked versions of SafeInt functions which operate directly on Float values.

import SafeInt.Unchecked as Unchecked

-- `2^40 / 10`
Unchecked.pow 2 40
    |> Unchecked.divBy 10
    --> 109951162777

It is recommended to use SafeInt functions instead of Unchecked functions, unless more speed is required at the cost of some lost safety and features.

Difference to SafeInt

Unchecked functions are faster than corresponding SafeInt functions because they

Therefore with Unchecked functions it's users responsibility to make sure that arguments are valid and such that result will be within allowed limits.

As long as undefined behavior is avoided, Unchecked functions will work exactly like corresponding SafeInt functions.

Usage rules

When using Unchecked functions

*) This doesn't apply to round, ceiling, truncate and floor which allow non-integer arguments.

If these rules are not followed, behavior of Unchecked functions is undefined.

Constants

minValue : Basics.Float

Minimum possible value, - (2^53 - 1) = - 9 007 199 254 740 991.

Equal to Number.MIN_SAFE_INTEGER in JavaScript.

SafeInt.Unchecked.minValue
    --> -9007199254740991

maxValue : Basics.Float

Maximum possible value, 2^53 - 1 = 9 007 199 254 740 991.

Equal to Number.MAX_SAFE_INTEGER in JavaScript.

SafeInt.Unchecked.maxValue
    --> 9007199254740991

Conversion from/to Int

fromInt : Basics.Int -> Basics.Float

Convert Int to Float.

Behavior is undefined if

Note: You can use Basics.toFloat instead of this function.

Note: Unlike SafeInt.fromInt, this function does not allow non-integer argument.

toInt : Basics.Float -> Basics.Int

Convert Float to Int.

Behavior is undefined if

Note: You can use Basics.round, Basics.floor or Basics.ceiling instead of this function.

Note: Unlike SafeInt.toInt, return value is Int instead of Maybe Int as Unchecked functions don't support undefined value.

Rounding

Comparison of rounding functions:

          -3.8 -3.5 -3.2   ~    3.2  3.5  3.8
          ---- ---- ----       ---- ---- ----
round     -4   -3   -3          3    4    4
ceiling   -3   -3   -3          4    4    4
truncate  -3   -3   -3          3    3    3
floor     -4   -4   -4          3    3    3

round : Basics.Float -> Basics.Float

Round to nearest integer and half towards positive infinity.

Behavior is undefined if argument is NaN, below minValue or above maxValue.

[ 3.2, 3.5, 3.8 ]
    |> List.map SafeInt.Unchecked.round
    --> [ 3.0, 4.0, 4.0 ]

[ -3.8, -3.5, -3.2 ]
    |> List.map SafeInt.Unchecked.round
    --> [ -4.0, -3.0, -3.0 ]

ceiling : Basics.Float -> Basics.Float

Round to integer towards positive infinity.

Behavior is undefined if argument is NaN, below minValue or above maxValue.

SafeInt.Unchecked.ceiling 3.8
    --> 4.0

SafeInt.Unchecked.ceiling -3.8
    --> -3.0

truncate : Basics.Float -> Basics.Float

Round to integer towards zero.

Behavior is undefined if argument is NaN, below minValue or above maxValue.

SafeInt.Unchecked.truncate 3.8
    --> 3.0

SafeInt.Unchecked.truncate -3.8
    --> -3.0

floor : Basics.Float -> Basics.Float

Round to integer towards negative infinity.

Behavior is undefined if argument is NaN, below minValue or above maxValue.

SafeInt.Unchecked.floor 3.8
    --> 3.0

SafeInt.Unchecked.floor -3.8
    --> -4.0

Math

add : Basics.Float -> Basics.Float -> Basics.Float

Addition.

Behavior is undefined if

Note: You can use + operator instead of this function.

sub : Basics.Float -> Basics.Float -> Basics.Float

Subtraction.

Behavior is undefined if

Note: You can use - operator instead of this function.

mul : Basics.Float -> Basics.Float -> Basics.Float

Multiplication.

Behavior is undefined if

Note: You can use * operator instead of this function.

pow : Basics.Float -> Basics.Float -> Basics.Float

Power aka exponentiation, rounding towards zero.

Behavior is undefined if

The table below shows the return values of pow a b near zero. U denotes undefined behavior and *0 denotes non-integer result rounded towards zero.

  b: -2 -1  0  1  2
 a   -- -- -- -- --
--
-2   *0 *0  1 -2  4
-1    1 -1  1 -1  1
 0    U  U  U  0  0
 1    1  1  1  1  1
 2   *0 *0  1  2  4

Example

SafeInt.Unchecked.pow 2 40
    --> 1099511627776

Note: Opinions differ on what the result of 0 ^ 0 should be. SafeInt takes the stance that when uncertain, it's undefined behavior. For more information see e.g. Zero to the power of zero🢅.

Division Basics

Division undefined

Behavior of division functions is undefined if

div : Basics.Float -> Basics.Float -> Basics.Float

Integer division, rounding towards negative infinity.

See Division undefined for undefined behavior and SafeInt § Division Basics for more information about division functions.

SafeInt.Unchecked.div 1234 100
    --> 12

SafeInt.Unchecked.div -1234 100
    --> -13

mod : Basics.Float -> Basics.Float -> Basics.Float

Remainder after div. This is also used for modular arithmetic🢅.

See Division undefined for undefined behavior and SafeInt § Division Basics for more information about division functions.

SafeInt.Unchecked.mod 1234 100
    --> 34

SafeInt.Unchecked.mod -1234 100
    --> 66

quotient : Basics.Float -> Basics.Float -> Basics.Float

Integer division, rounding towards zero.

This is similar to // operator.

See Division undefined for undefined behavior and SafeInt § Division Basics for more information about division functions.

SafeInt.Unchecked.quotient 1234 100
    --> 12

SafeInt.Unchecked.quotient -1234 100
    --> -12

remainder : Basics.Float -> Basics.Float -> Basics.Float

Remainder after quotient.

See Division undefined for undefined behavior and SafeInt § Division Basics for more information about division functions.

SafeInt.Unchecked.remainder 1234 100
    --> 34

SafeInt.Unchecked.remainder -1234 100
    --> -34

Division Reversed

Functions divBy, modBy, quotientBy and remainderBy are same as basic division functions, except with reversed arguments.

modBy is similar to Basics.modBy and remainderBy to Basics.remainderBy.

import SafeInt.Unchecked as Unchecked

-- `2^40 / 10`
Unchecked.pow 2 40
    |> Unchecked.divBy 10
    --> 109951162777

divBy : Basics.Float -> Basics.Float -> Basics.Float

Same as div except with reversed arguments.

modBy : Basics.Float -> Basics.Float -> Basics.Float

Same as mod except with reversed arguments.

This is similar to Basics.modBy.

quotientBy : Basics.Float -> Basics.Float -> Basics.Float

Same as quotient except with reversed arguments.

remainderBy : Basics.Float -> Basics.Float -> Basics.Float

Same as remainder except with reversed arguments.

This is similar to Basics.remainderBy.

Division Combined

divMod : Basics.Float -> Basics.Float -> ( Basics.Float, Basics.Float )

Combines div and mod into a single function.

divMod a b is same as ( div a b, mod a b ) except faster.

SafeInt.Unchecked.divMod 1234 100
    --> ( 12, 34 )

SafeInt.Unchecked.divMod -1234 100
    --> ( -13, 66 )

quotRem : Basics.Float -> Basics.Float -> ( Basics.Float, Basics.Float )

Combines quotient and remainder into a single function.

quotRem a b is same as ( quotient a b, remainder a b ) except faster.

SafeInt.Unchecked.quotRem 1234 100
    --> ( 12, 34 )

SafeInt.Unchecked.quotRem -1234 100
    --> ( -12, -34 )

divModBy : Basics.Float -> Basics.Float -> ( Basics.Float, Basics.Float )

Same as divMod except with reversed arguments.

quotRemBy : Basics.Float -> Basics.Float -> ( Basics.Float, Basics.Float )

Same as quotRem except with reversed arguments.

Signs

abs : Basics.Float -> Basics.Float

Absolute value.

Behavior is undefined if

Note: You can use Basics.abs instead of this function.

negate : Basics.Float -> Basics.Float

Negation.

Behavior is undefined if

Note: You can use Basics.negate instead of this function.

sign : Basics.Float -> Basics.Float

Sign.

Behavior is undefined if

Examples

SafeInt.Unchecked.sign 123
    --> 1

SafeInt.Unchecked.sign -123
    --> -1