64-bit unsigned integer using wrapping overflow.
64-bit unsigned integer.
UInt64
is represented internally as three unsigned integers:
high
: 16-bit unsigned integer for bits 48 - 63mid
: 24-bit unsigned integer for bits 24 - 47low
: 24-bit unsigned integer for bits 0 - 23minValue : UInt64
Minimum possible UInt64
value.
Same as zero
.
UInt64.minValue
|> UInt64.toString
--> "0"
maxValue : UInt64
Maximum possible UInt64
value.
2^64 - 1 = 18446744073709551615 = 0xFFFFFFFFFFFFFFFF
UInt64.maxValue
|> UInt64.toString
--> "18446744073709551615"
maxSafe : UInt64
Maximum safe integer as UInt64
.
2^53 - 1 = 9007199254740991 = 0x001FFFFFFFFFFFFF
Equal to Number.MAX_SAFE_INTEGER
in JavaScript.
See also isSafe
.
maxSafeAsFloat : Basics.Float
maxSafe
as Float
maxFloat : UInt64
Maximum UInt64
value that can be represented exactly as a Float
.
2^64 - 2048 = 18446744073709549568 = 0xFFFFFFFFFFFFF800
Note: Float
can't represent exactly all integers above maxSafe
.
For example integers maxFloat
+ 1 <= x <=
maxValue
can't be represented exactly as Float
,
making this the maximum UInt64
value that can.
maxFloatAsFloat : Basics.Float
maxFloat
as Float
zero : UInt64
Number 0
one : UInt64
Number 1
two : UInt64
Number 2
Every Int
or Float
argument of every UInt64
function is limited
by one of the following three functions (or equivalent code):
Int
and valid value is 0 <= x < 2^n
, n <= 32
limitSmallInt
n True value
.Int
and valid value is 1 <= x <= 2^n
, n <= 32
limitSmallInt
n False value
.Int
and valid value can be above 2^32
limitLargeInt
value
.Float
and valid value is 0 <= x <= max
limitFloat
max value
.Int
Int
arguments are expected to be integers
and are not checked for non-integer values like NaN
, -Infinity
, +Infinity
or 12.34
.
Behavior of any UInt64
function is undefined if Int
argument is not an integer.
Int
Behavior of Int
for values above 2^31 - 1
is undefined in Elm.
As of Elm 0.19.1, using Int
as function parameter or return value works for full safe integer range
up to maxSafe
, but this could change in the future.
Note: This affects also limitSmallInt
with n = 32
.
String
String
argument can be any valid Unicode String
.
Behavior is undefined if String
argument contains invalid Unicode.
Such String
:s can't be fuzz-tested with elm-test
,
so I can't make functions robust against invalid Unicode.
limitSmallInt : Basics.Int -> Basics.Bool -> Basics.Int -> Basics.Int
Limit Int
to 0 <= x < 2 ^ bitSize
or 1 <= x <= 2 ^ bitSize
.
bitSize
: 1 <= bitSize <= 32
startFromZero
True
if valid range is 0 <= x < 2 ^ bitSize
False
if valid range is 1 <= x <= 2 ^ bitSize
value
: value to limitSee argument handling.
Algorithm:
2 ^ bitSize - 1
.not startFromZero
, use 2 ^ bitSize
as value.-- `1234` limited to 6 bits, `0 <= x <= 63`
UInt64.limitSmallInt 6 True 1234
--> 18
-- `-1` limited to 8 bits, `0 <= x <= 255`
UInt64.limitSmallInt 8 True -1
--> 0xFF
-- `-1` limited to 32 bits, `0 <= x <= 2^32-1`
UInt64.limitSmallInt 32 True -1
--> 0xFFFFFFFF
-- `0` limited to 6 bits, `1 <= x <= 64`
UInt64.limitSmallInt 6 False 0
--> 64
limitLargeInt : Basics.Int -> Basics.Int
Limit Int
to 0 <= value <=
maxSafe
.
See argument handling.
Algorithm:
-- negative value is replaced with zero
UInt64.limitLargeInt -1
--> 0
-- value above `maxSafe` is replaced with `maxSafe`
UInt64.limitLargeInt 9007199254740992
--> 9007199254740991
limitFloat : Basics.Float -> Basics.Float -> Basics.Float
Limit Float
to 0 <= value <= max
.
max
: maximum allowed value, max <=
maxFloat
value
: value to limitSee argument handling.
Algorithm:
NaN
, use 0
instead.0
instead.max
, use max
instead.-- `-1` limited to 12 decimal digits
UInt64.limitFloat 999999999999 -1
--> 0
-- `1e20` limited to 12 decimal digits
UInt64.limitFloat 999999999999 1e20
--> 999999999999
-- `1e20` limited to `0 <= value <= maxFloat`
UInt64.limitFloat UInt64.maxFloatAsFloat 1.0e20
--> 18446744073709549568.0
fromInt : Basics.Int -> UInt64
Convert Int
to UInt64
.
value
: 0 <= x <=
maxSafe
See argument handling.
UInt64.fromInt 123
|> UInt64.toString
--> "123"
toInt31 : UInt64 -> Maybe Basics.Int
Convert UInt64
to 31-bit unsigned integer.
If UInt64
is above 2^31 - 1
, return Nothing
.
UInt64.fromInt 0x7FFFFFFF
|> UInt64.toInt31
--> Just 0x7FFFFFFF
UInt64.fromInt 0x80000000
|> UInt64.toInt31
--> Nothing
toInt53 : UInt64 -> Maybe Basics.Int
Convert UInt64
to 53-bit unsigned integer.
If UInt64
is above maxSafe
, return Nothing
.
See large Int
note.
UInt64.maxSafe
|> UInt64.toInt53
--> Just 9007199254740991
UInt64.maxSafe
|> UInt64.increment
|> UInt64.toInt53
--> Nothing
floor : Basics.Float -> UInt64
Convert Float
to UInt64
, rounding down.
value
: 0 <= x <=
maxFloat
**) If value
is above maxValue
, return maxValue
.
See argument handling.
Conversion is exact for all possible Float
integer values from 0
to maxFloat
.
However because Float
can't represent all integers above maxSafe
,
it can sometimes seem like there is an error.
In the following example value 11222333444555666777.0
can't be represented exactly as a Float
.
Nearest value that can be represented exactly as a Float
is 11222333444555667456.0
,
and that is what UInt64.floor
gets as its argument.
This argument is then converted exactly to UInt64
.
UInt64.floor 11222333444555666777.0
|> UInt64.toString
--> "11222333444555667456"
fromDecimal12s
can be used instead
to convert decimal literals above maxSafe
to UInt64
:
UInt64.fromDecimal12s 11222333 444555666777
|> UInt64.toString
--> "11222333444555666777"
toFloat : UInt64 -> Basics.Float
Convert UInt64
to Float
.
Conversion is exact for any value from 0
to maxSafe
,
but above maxSafe
value is rounded if it can't be represented exactly as Float
.
9007199254740993
can't be represented exactly as Float
,
so it's rounded to 9007199254740992
.
UInt64.fromDecimal12s 9007 199254740993
|> UInt64.toFloat
--> 9007199254740992
fromInt32s : Basics.Int -> Basics.Int -> UInt64
Convert 64-bit unsigned integer represented as two 32-bit unsigned integers to UInt64
.
high
: 32-bit unsigned integer for bits 32 - 63low
: 32-bit unsigned integer for bits 0 - 31See argument handling.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.toHexString
--> "11223344AABBCCDD"
UInt64.fromInt32s 1 2
|> UInt64.toHexString
--> "0000000100000002"
toInt32s : UInt64 -> ( Basics.Int, Basics.Int )
Convert UInt64
to 64-bit unsigned integer represented as two 32-bit unsigned integers.
high
: 32-bit unsigned integer for bits 32 - 63low
: 32-bit unsigned integer for bits 0 - 31See large Int
note.
UInt64.floor 1e15
|> UInt64.toInt32s
--> ( 0x00038D7E, 0xA4C68000 )
fromInt24s : Basics.Int -> Basics.Int -> Basics.Int -> UInt64
Convert 64-bit unsigned integer represented as three 24-bit unsigned integers to UInt64
.
This is the internal format of UInt64
and so fromInt24s
is the fastest way to create UInt64
value.
high
: 16-bit unsigned integer for bits 48 - 63mid
: 24-bit unsigned integer for bits 24 - 47low
: 24-bit unsigned integer for bits 0 - 23See argument handling.
UInt64.fromInt24s 0x1122 0x334455 0x667788
|> UInt64.toHexString
--> "1122334455667788"
UInt64.fromInt24s 1 2 3
|> UInt64.toHexString
--> "0001000002000003"
toInt24s : UInt64 -> ( Basics.Int, Basics.Int, Basics.Int )
Convert UInt64
to 64-bit unsigned integer represented as three 24-bit unsigned integers.
This is the internal format of UInt64
and so toInt24s
is the fastest way to extract value out of UInt64
.
high
: 16-bit unsigned integer for bits 48 - 63mid
: 24-bit unsigned integer for bits 24 - 47low
: 24-bit unsigned integer for bits 0 - 23UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.toInt24s
--> ( 0x1122, 0x3344AA, 0xBBCCDD )
fromDecimal12s : Basics.Float -> Basics.Float -> UInt64
Convert 64-bit unsigned integer represented as two 12-decimal-digit unsigned integers to UInt64
.
high
: 8 highest digits, 0 <= high <= 18446745
*low
: 12 lowest digits, 0 <= low <= 999999999999
*) If high
is 18446745
, return maxValue
.
See argument handling.
UInt64.fromDecimal12s 111222 333444555666
|> UInt64.toString
--> "111222333444555666"
UInt64.fromDecimal12s 1 2
|> UInt64.toString
--> "1000000000002"
fromBigEndianBytes : List Basics.Int -> UInt64
Convert list of bytes in big-endian order to UInt64
.
byte
: 0 <= x <= 255
See argument handling.
UInt64.fromBigEndianBytes [ 0xAB, 0, 0xCD ]
|> UInt64.toHexString
--> "0000000000AB00CD"
List.range 0x01 0x0F
|> UInt64.fromBigEndianBytes
|> UInt64.toHexString
--> "08090A0B0C0D0E0F"
toBigEndianBytes : UInt64 -> List Basics.Int
Convert UInt64
to list of 8 bytes in big-endian order.
UInt64.fromInt 0xABCDEF
|> UInt64.toBigEndianBytes
--> [ 0, 0, 0, 0, 0, 0xAB, 0xCD, 0xEF ]
fromString : String -> Maybe UInt64
Convert String
to UInt64
.
String
can be
String
of digits 0123456789
String
with prefix 0x
and digits 0123456789ABCDEFabcdef
String
with prefix 0o
and digits 01234567
String
with prefix 0b
and digits 01
Return Nothing
if String
isn't valid for any of the above formats,
or if the value would be above maxValue
.
See String
at argument handling.
UInt64.fromString "12345"
|> Maybe.andThen UInt64.toInt31
--> Just 12345
UInt64.fromString "0x11223344AABBCCDD"
|> Maybe.map UInt64.toInt32s
--> Just ( 0x11223344, 0xAABBCCDD )
UInt64.fromString "0o777"
|> Maybe.map UInt64.toHexString
--> Just "00000000000001FF"
UInt64.fromString "0b1111000011110000"
|> Maybe.map UInt64.toHexString
--> Just "000000000000F0F0"
-- `e` is not valid without `0x` prefix
UInt64.fromString "1e10"
--> Nothing
-- value would be above `maxValue`
UInt64.fromString "111222333444555666777"
--> Nothing
toString : UInt64 -> String
Convert UInt64
to decimal String
.
UInt64.fromInt 0xFFFFFF
|> UInt64.toString
--> "16777215"
Note: See Conversion - Digits for more options
converting UInt64
toString
.
toHexString : UInt64 -> String
Convert UInt64
to uppercase hexadecimal String
of 16 characters.
UInt64.floor 1e15
|> UInt64.toHexString
--> "00038D7EA4C68000"
UInt64.zero
|> UInt64.toHexString
--> "0000000000000000"
Note: See Conversion - Digits for more options
converting UInt64
toString
.
These functions convert UInt64
to Digits
,
which offers options like different bases, digits padding and digits grouping.
toDigits : Internal.Base -> UInt64 -> Internal.Digits Char
Convert UInt64
to Digits
of Char
using given Base
.
This is intended as first step in converting UInt64
to String
.
import UInt64
import UInt64.Digits as Digits
UInt64.maxValue
|> UInt64.toDigits Digits.octal
|> Digits.toString
--> "1777777777777777777777"
UInt64.floor 1e15
|> UInt64.toDigits Digits.hexLower
|> Digits.padToMultipleOf 4 '0'
|> Digits.groupToString 4 ' '
--> "0003 8d7e a4c6 8000"
toIntDigits : Internal.Base -> UInt64 -> Internal.Digits Basics.Int
Convert UInt64
to Digits
of Int
using given Base
.
This is like toDigits
except that each digit will be Int
instead of Char
.
import UInt64
import UInt64.Digits as Digits
UInt64.fromInt 0xABC
|> UInt64.toIntDigits Digits.hex
|> Digits.toList
--> [ 10, 11, 12 ]
-- digit sum of 1234 is `1+2+3+4 = 10`
UInt64.fromInt 1234
|> UInt64.toIntDigits Digits.decimal
|> Digits.toList
|> List.sum
--> 10
add : UInt64 -> UInt64 -> UInt64
Addition with wrapping overflow.
-- `123 + 456`
UInt64.add (UInt64.fromInt 123) (UInt64.fromInt 456)
|> UInt64.toString
--> "579"
-- `maxValue + 100`
UInt64.add UInt64.maxValue (UInt64.fromInt 100)
|> UInt64.toString
--> "99"
sub : UInt64 -> UInt64 -> UInt64
Subtraction with wrapping overflow.
-- `456 - 123`
UInt64.sub (UInt64.fromInt 456) (UInt64.fromInt 123)
|> UInt64.toString
--> "333"
-- `0 - 0xFF`
UInt64.sub UInt64.zero (UInt64.fromInt 0xFF)
|> UInt64.toHexString
--> "FFFFFFFFFFFFFF01"
mul : UInt64 -> UInt64 -> UInt64
Multiplication with wrapping overflow.
-- `1e9 * 1e9`
UInt64.mul (UInt64.floor 1e9) (UInt64.floor 1e9)
|> UInt64.toString
--> "1000000000000000000"
-- `(1e10 * 1e10) % 2^64`
UInt64.mul (UInt64.floor 1e10) (UInt64.floor 1e10)
|> UInt64.toString
--> "7766279631452241920"
pow : UInt64 -> UInt64 -> UInt64
Power aka exponentiation. 0 ^ 0 = 1
-- `3 ^ 7`
UInt64.pow (UInt64.fromInt 3) (UInt64.fromInt 7)
|> UInt64.toString
--> "2187"
-- `10 ^ 19`
UInt64.pow (UInt64.fromInt 10) (UInt64.fromInt 19)
|> UInt64.toString
--> "10000000000000000000"
-- `(3 ^ 10000000000000000000) % 2^64`
UInt64.pow (UInt64.fromInt 10) (UInt64.fromInt 19)
|> UInt64.pow (UInt64.fromInt 3)
|> UInt64.toString
--> "12038004833498693633"
Note: Uses fast algorithms: Bases 0-2 are special-cased, exponents 0-16 use addition-chain exponentiation🢅 and exponents over 16 use exponentiation by squaring🢅.
increment : UInt64 -> UInt64
Increment by one with wrapping overflow.
-- `42 + 1`
UInt64.increment (UInt64.fromInt 42)
|> UInt64.toString
--> "43"
-- `maxValue + 1`
UInt64.increment UInt64.maxValue
|> UInt64.toString
--> "0"
decrement : UInt64 -> UInt64
Decrement by one with wrapping overflow.
-- `42 - 1`
UInt64.decrement (UInt64.fromInt 42)
|> UInt64.toString
--> "41"
-- `0 - 1`
UInt64.decrement UInt64.zero
|> UInt64.toHexString
--> "FFFFFFFFFFFFFFFF"
square : UInt64 -> UInt64
Squaring with wrapping overflow.
square a
is same as mul a a
or pow a two
but faster.
-- `1e9 * 1e9`
UInt64.square (UInt64.floor 1e9)
|> UInt64.toString
--> "1000000000000000000"
Note: I would prefer to cause runtime exception on division-by-zero,
but that can't be tested, so I'll settle for returning zero
which can be tested.
div : UInt64 -> UInt64 -> UInt64
Integer division.
UInt64.div (UInt64.fromInt 1234) (UInt64.fromInt 100)
|> UInt64.toFloat
--> 12
-- 0xFFFFFFFFFFFFFFFF / 1e10
UInt64.div UInt64.maxValue (UInt64.floor 1e10)
|> UInt64.toFloat
--> 1844674407
mod : UInt64 -> UInt64 -> UInt64
Remainder after div
.
UInt64.mod (UInt64.fromInt 1234) (UInt64.fromInt 100)
|> UInt64.toFloat
--> 34
-- 0xFFFFFFFFFFFFFFFF % 1e10
UInt64.mod UInt64.maxValue (UInt64.floor 1e10)
|> UInt64.toFloat
--> 3709551615
divMod : UInt64 -> UInt64 -> ( UInt64, UInt64 )
Integer division with modulo.
divMod a b
is same as ( div a b, mod a b )
but faster.
zero
, return ( zero, zero )
.UInt64.divMod (UInt64.fromInt 1234) (UInt64.fromInt 100)
|> Tuple.mapBoth UInt64.toFloat UInt64.toFloat
--> ( 12, 34 )
-- ( 0xFFFFFFFFFFFFFFFF / 1e10, 0xFFFFFFFFFFFFFFFF % 1e10 )
UInt64.divMod UInt64.maxValue (UInt64.floor 1e10)
|> Tuple.mapBoth UInt64.toFloat UInt64.toFloat
--> ( 1844674407, 3709551615 )
and : UInt64 -> UInt64 -> UInt64
Bitwise AND.
UInt64.and
(UInt64.fromInt32s 0x11223344 0xAABBCCDD)
(UInt64.fromInt32s 0x0000FFFF 0xFFFF0000)
|> UInt64.toHexString
--> "00003344AABB0000"
or : UInt64 -> UInt64 -> UInt64
Bitwise OR.
UInt64.or
(UInt64.fromInt32s 0x11223344 0xAABBCCDD)
(UInt64.fromInt32s 0x0000FFFF 0xFFFF0000)
|> UInt64.toHexString
--> "1122FFFFFFFFCCDD"
xor : UInt64 -> UInt64 -> UInt64
Bitwise XOR.
UInt64.xor
(UInt64.fromInt32s 0x11223344 0xAABBCCDD)
(UInt64.fromInt32s 0x0000FFFF 0xFFFF0000)
|> UInt64.toHexString
--> "1122CCBB5544CCDD"
complement : UInt64 -> UInt64
Bitwise complement, aka bitwise NOT, aka one's complement.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.complement
|> UInt64.toHexString
--> "EEDDCCBB55443322"
shiftLeftBy : Basics.Int -> UInt64 -> UInt64
Bitwise shift left, filling with zeroes from right.
shift
: 0 <= x <= 63
See argument handling.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.shiftLeftBy 20
|> UInt64.toHexString
--> "344AABBCCDD00000"
shiftRightZfBy : Basics.Int -> UInt64 -> UInt64
Bitwise shift right, filling with zeroes from left.
shift
: 0 <= x <= 63
See argument handling.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.shiftRightZfBy 20
|> UInt64.toHexString
--> "0000011223344AAB"
rotateLeftBy : Basics.Int -> UInt64 -> UInt64
Bitwise rotate left.
shift
: 0 <= x <= 63
See argument handling.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.rotateLeftBy 20
|> UInt64.toHexString
--> "344AABBCCDD11223"
rotateRightBy : Basics.Int -> UInt64 -> UInt64
Bitwise rotate right.
shift
: 0 <= x <= 63
See argument handling.
UInt64.fromInt32s 0x11223344 0xAABBCCDD
|> UInt64.rotateRightBy 20
|> UInt64.toHexString
--> "BCCDD11223344AAB"
shiftRightZfBy1 : UInt64 -> UInt64
Bitwise shift right by one bit, filling with zero from left.
shiftRightZfBy1 a
is same as shiftRightZfBy 1 a
but faster.
UInt64.fromInt32s 0xEECCAA88 0x66442200
|> UInt64.shiftRightZfBy1
|> UInt64.toHexString
--> "7766554433221100"
getBit : Basics.Int -> UInt64 -> Basics.Int
Return a bit.
bitNumber
: 0 <= x <= 63
, least significant bit is 0
See argument handling.
UInt64.one
|> UInt64.getBit 0
--> 1
setBit : Basics.Int -> Basics.Int -> UInt64 -> UInt64
Set a bit to given value.
bitNumber
: 0 <= x <= 63
, least significant bit is 0
bitValue
: new value, either 0
or 1
See argument handling.
UInt64.zero
|> UInt64.setBit 30 1
|> UInt64.toHexString
--> "0000000040000000"
compare : UInt64 -> UInt64 -> Basics.Order
Compare two UInt64
:s.
UInt64.compare UInt64.zero UInt64.one
--> LT
isSafe : UInt64 -> Basics.Bool
Return True
if argument is safe integer.
A safe integer is an integer that
Float
andFloat
.Unsigned integers from 0
to maxSafe
are safe integers.
For example 2^53
is not a safe integer.
While it can be represented exactly as Float
,
there exists another integer 2^53 + 1
which is rounded to 2^53
:
-- 2^53 + 1 (9007199254740993) is rounded to
-- 2^53 (9007199254740992) when converted to Float
UInt64.fromDecimal12s 9007 199254740993
|> UInt64.toFloat
--> 9007199254740992
UInt64.fromDecimal12s 9007 199254740993
|> UInt64.isSafe
--> False
This happens because 2^53 + 1
can't be represented exactly as Float
,
so it is rounded to another integer.
isZero : UInt64 -> Basics.Bool
Return True
if argument is zero
.
This is same as (==)
zero
but much faster.
Note: See Performance Optimization🢅 for discussion about speed of ==
in Elm 0.19.1.
isEven : UInt64 -> Basics.Bool
Return True
if argument is even.
isOdd : UInt64 -> Basics.Bool
Return True
if argument is odd.
Extra functions which can be useful for some use cases, e.g. benchmarking and testing.
These are not intended to be useful generally.
divModFast : UInt64 -> UInt64 -> Result String ( UInt64, UInt64 )
Fast but complex algorithm for integer division with modulo.
zero
, return Ok ( zero, zero )
.Err error
.divModSlow
.You should usually use divMod
instead because it will use
even faster algorithms when dividend < 2^53
or divisor < 2^29
,
and will fall back to divModFast
otherwise.
So divModFast
is faster than divMod
only when
dividend >= 2^53 && divisor >= 2^29
.
divModSlow : UInt64 -> UInt64 -> ( UInt64, UInt64 )
Simple but slow long division🢅 algorithm for integer division with modulo.
zero
, return ( zero, zero )
.Intended use cases:
divModFast
,
in case it returns Err
. Which should never happen.