std.int.Int
Valuetype pub builtin Int
A 64-bits signed integer type.
Int
values can represent values in the range
-9223372036854775808 <= value <= 9223372036854775807
.
Overflows
Methods used for operators such as Int.+
and Int.>>
change their behavior
based on the mode (debug or release) used for compiling code. In debug mode
such methods trigger a panic upon overflow, while in release mode they wrap
using two's complement. This makes it easier to catch unintended overflows,
while still allowing for efficient code generation when using the release
mode.
Static methods
parse
Show source codeHide source code
fn pub static parse[T: Bytes](
bytes: ref T,
format: ref Format,
) -> Option[Int] {
let base = format.to_base
let len = bytes.size
let mut idx = 0
let pos = match bytes.get(idx) {
case Ok(PLUS) -> {
idx += 1
if idx == len { return Option.None } else { true }
}
case Ok(MINUS) -> {
idx += 1
if idx == len { return Option.None } else { false }
}
case Ok(_) -> true
case _ -> return Option.None
}
let mut num = 0
# For base 16 numbers, we allow them to start with -0x and 0x, as most base
# 16 numbers will likely use the format 0xABC and not just ABC.
if base == 16 and bytes.get(idx).or(-1) == ZERO {
match bytes.get(idx + 1) {
case Ok(LOWER_X) -> {
idx += 2
if idx == len { return Option.None }
}
case _ -> {}
}
}
# Rust's approach is to check if an overflow is possible, and use wrapped
# arithmetic in that case, in an attempt to improve performance. This was
# implemented in https://github.com/rust-lang/rust/pull/95399, with
# https://github.com/rust-lang/rust/pull/83371 and
# https://github.com/rust-lang/rust/pull/83088 being related pull requests.
#
# I opted not to take this approach at the time of writing, as the
# performance improvements seem very small, and simply not worth the extra
# code at the time of writing. If this ever changes, we can consider taking
# a similar approach.
while idx < len {
let digit = match bytes.get(idx).or_panic {
case v if digit?(v) -> v - ZERO
case v if v >= LOWER_A and v <= LOWER_F -> v - LOWER_A + 10
case v if v >= UPPER_A and v <= UPPER_F -> v - UPPER_A + 10
case _ -> return Option.None
}
if digit > base or digit < 0 { return Option.None }
num = try num.checked_mul(base)
num = try if pos {
num.checked_add(digit)
} else {
num.checked_sub(digit)
}
idx += 1
}
Option.Some(num)
}
fn pub static parse[T: Bytes](bytes: ref T, format: Format) -> Option[Int]
Parses a Bytes
into an Int
in the format specified in format
,
returning a Some
if the value is valid, and a None
otherwise.
For numbers in binary, the valid digits are 0
and 1
. For decimal numbers,
the valid digits are in the range 0-9
. For hexadecimal numbers, the valid
digits are in the ranges a-z
, A-Z
, 0-9
, and the input may start with
0x
.
In addition, the input may start with +
or -
, regardless of the input
format.
Leading and/or trailing whitespace is considered invalid.
Examples
Parsing a binary number:
import std.int (Format)
Int.parse('11', Format.Binary) # => Option.Some(3)
Int.parse('-11', Format.Binary) # => Option.Some(-3)
Int.parse('ff', Format.Binary) # => Option.None
Parsing a decimal number:
import std.int (Format)
Int.parse('123', Format.Decimal) # => Option.Some(123)
Int.parse('-123', Format.Decimal) # => Option.Some(-123)
Int.parse('abc', Format.Decimal) # => Option.None
Parsing a hexadecimal number:
import std.int (Format)
Int.parse('ef', Format.Hex) # => Option.Some(239)
Int.parse('0xef', Format.Hex) # => Option.Some(239)
Int.parse('-0xef', Format.Hex) # => Option.Some(-239)
Int.parse('zz', Format.Hex) # => Option.None
sum
Show source codeHide source code
fn pub static sum[I: Iter[Int]](iterator: move I) -> Int {
iterator.reduce(0, fn (acc, val) { acc + val })
}
fn pub static sum[I: Iter[Int]](iterator: move I) -> Int
Sums the values of iterator
into a single Int
.
Examples
Int.sum([10, 20, 30].into_iter) # => 60
Instance methods
!=
Show source codeHide source code
fn pub inline !=(other: ref Int) -> Bool {
_INKO.int_ne(self, other)
}
fn pub inline !=(other: Int) -> Bool
Returns true
if self
and the given object are not equal to each other.
%
Show source codeHide source code
fn pub inline %(other: Int) -> Int {
mode.mod(self, other)
}
fn pub inline %(other: Int) -> Int
Returns the remainder of dividing self
by other
.
Examples
10 % 3 # => 1
Overflows
In debug mode, this method triggers a panic upon overflowing. In release mode, two's complement wrapping is used instead.
Panics
This method always panics (regardless of the mode used) if any of the following is true:
other
is equal to zeroself
is equal tostd.int.MIN
andother
is equal to -1
&
Show source codeHide source code
fn pub inline &(other: ref Int) -> Int {
_INKO.int_bit_and(self, other)
}
fn pub inline &(other: Int) -> Int
Returns the result of a bitwise AND with self
and the given object.
*
Show source codeHide source code
fn pub inline *(other: Int) -> Int {
mode.mul(self, other)
}
fn pub inline *(other: Int) -> Int
Multiplies other
with self
.
Examples
10 * 2 # => 20
Overflows
In debug mode, this method triggers a panic upon overflowing. In release mode, two's complement wrapping is used instead.
**
Show source codeHide source code
fn pub inline **(other: ref Int) -> Int {
mode.pow(self, other)
}
fn pub inline **(other: Int) -> Int
Raises self
to the power of other
.
Examples
10 ** 2 # => 100
Overflows
In debug mode, this method triggers a panic upon overflowing. In release mode, two's complement wrapping is used instead.
+
Show source codeHide source code
fn pub inline +(other: Int) -> Int {
mode.add(self, other)
}
fn pub inline +(other: Int) -> Int
Adds other
to self
.
Examples
10 + 2 # => 12
Overflows
In debug mode, this method triggers a panic upon overflowing. In release mode, two's complement wrapping is used instead.
-
Show source codeHide source code
fn pub inline -(other: Int) -> Int {
mode.sub(self, other)
}
fn pub inline -(other: Int) -> Int
Subtracts other
from self
.
Examples
10 - 2 # => 8
Overflows
In debug mode, this method triggers a panic upon overflowing. In release mode, two's complement wrapping is used instead.
/
Show source codeHide source code
fn pub inline /(other: ref Int) -> Int {
if other == 0 or (self == MIN and other == -1) { overflow_error }
unchecked_div(other)
}
fn pub inline /(other: Int) -> Int
Divides self
by other
.
Panics
This method panics if other
is zero, or if self
is MIN
and other
is
-1
. This is true for both debug and release builds.
<
Show source codeHide source code
fn pub inline <(other: ref Int) -> Bool {
_INKO.int_lt(self, other)
}
fn pub inline <(other: Int) -> Bool
Returns true
if self
is lower than the given argument.
<<
Show source codeHide source code
fn pub inline <<(other: Int) -> Int {
mode.shl(self, other)
}
fn pub inline <<(other: Int) -> Int
Shifts self
by other
bits to the left.
Examples
10 << 1 # => 20
1 << 65 # => 2
Overflows
In debug mode, this method triggers a panic if other
is greater than 63.
In release mode, a bitmask is applied to other
such that it wraps around
when the value is greater than 63
(i.e. 64
is treated as 1
).
<=
Show source codeHide source code
fn pub inline <=(other: ref Int) -> Bool {
_INKO.int_le(self, other)
}
fn pub inline <=(other: Int) -> Bool
Returns true
if self
is lower than or equal to the given argument.
==
Show source codeHide source code
fn pub inline ==(other: ref Int) -> Bool {
_INKO.int_eq(self, other)
}
fn pub inline ==(other: Int) -> Bool
Returns true
if self
and the given object are equal to each other.
This operator is used to perform structural equality. This means two objects residing in different memory locations may be considered equal, provided their structure is equal. For example, two different arrays may be considered to have structural equality if they contain the exact same values.
>
Show source codeHide source code
fn pub inline >(other: ref Int) -> Bool {
_INKO.int_gt(self, other)
}
fn pub inline >(other: Int) -> Bool
Returns true
if self
is greater than the given argument.
>=
Show source codeHide source code
fn pub inline >=(other: ref Int) -> Bool {
_INKO.int_ge(self, other)
}
fn pub inline >=(other: Int) -> Bool
Returns true
if self
is equal to or greater than the given argument.
>>
Show source codeHide source code
fn pub inline >>(other: Int) -> Int {
mode.shr(self, other)
}
fn pub inline >>(other: Int) -> Int
Shifts self
by other
bits to the right.
Examples
10 >> 1 # => 5
10 >> 65 # => 5
-10 >> 2 # => -3
Overflows
In debug mode, this method triggers a panic if other
is greater than 63.
In release mode, a bitmask is applied to other
such that it wraps around
when the value is greater than 63
(i.e. 64
is treated as 1
).
>>>
Show source codeHide source code
fn pub inline >>>(other: Int) -> Int {
mode.ushr(self, other)
}
fn pub inline >>>(other: Int) -> Int
Shifts self
by other
bits to the right, treating self
as an unsigned
integer as part of the shift.
Examples
10 >>> 2 # => 2
-10 >>> 2 # => 4611686018427387901
Overflows
In debug mode, this method triggers a panic if other
is greater than 63.
In release mode, a bitmask is applied to other
such that it wraps around
when the value is greater than 63
(i.e. 64
is treated as 1
).
^
Show source codeHide source code
fn pub inline ^(other: ref Int) -> Int {
_INKO.int_bit_xor(self, other)
}
fn pub inline ^(other: Int) -> Int
Returns the result of a bitwise XOR with self
and the given object.
absolute
Show source codeHide source code
fn pub inline absolute -> Int {
_INKO.int_absolute(self)
}
fn pub inline absolute -> Int
Returns the absolute value of self
.
If self
is equal to std.int.MIN
, then the returned value is also
std.int.MIN
.
Examples
-4.absolute # => 4
4.absolute # => 4
-9_223_372_036_854_775808.absolute # => -9_223_372_036_854_775808
checked_add
Show source codeHide source code
fn pub inline checked_add(other: Int) -> Option[Int] {
let res = _INKO.int_checked_add(self, other)
if res.tag as Int == 0 {
Option.Some(res.value as Int)
} else {
Option.None
}
}
fn pub inline checked_add(other: Int) -> Option[Int]
Adds other
to self
, returning a None
when overflowing.
Examples
import std.int (MAX)
1.checked_add(5) # => Option.Some(6)
MAX.checked_add(1) # => Option.None
checked_div
Show source codeHide source code
fn pub inline checked_div(other: Int) -> Option[Int] {
if other == 0 or (self == MIN and other == -1) {
Option.None
} else {
Option.Some(unchecked_div(other))
}
}
fn pub inline checked_div(other: Int) -> Option[Int]
Divides self
by other
, returning a None
when overflowing or if other
is zero.
Examples
import std.int (MAX)
10.checked_div(0) # => Option.None
10.checked_div(2) # => Option.Some(5)
checked_mul
Show source codeHide source code
fn pub inline checked_mul(other: Int) -> Option[Int] {
let res = _INKO.int_checked_mul(self, other)
if res.tag as Int == 0 {
Option.Some(res.value as Int)
} else {
Option.None
}
}
fn pub inline checked_mul(other: Int) -> Option[Int]
Multiplies other
with self
, returning a None
when overflowing.
Examples
import std.int (MAX)
1.checked_mul(2) # => Option.Some(2)
MAX.checked_mul(2) # => Option.None
checked_pow
Show source codeHide source code
fn pub inline checked_pow(other: Int) -> Option[Int] {
let res = inko_int_checked_pow(self, other)
if res.tag as Int == 0 {
Option.Some(res.value as Int)
} else {
Option.None
}
}
fn pub inline checked_pow(other: Int) -> Option[Int]
Raises self
to the power of other
, returning a None
when overflowing.
Examples
import std.int (MAX)
2.checked_pow(2) # => Option.Some(4)
MAX.checked_pow(2) # => Option.None
checked_sub
Show source codeHide source code
fn pub inline checked_sub(other: Int) -> Option[Int] {
let res = _INKO.int_checked_sub(self, other)
if res.tag as Int == 0 {
Option.Some(res.value as Int)
} else {
Option.None
}
}
fn pub inline checked_sub(other: Int) -> Option[Int]
Subtracts other
from self
, returning a None
when overflowing.
Examples
import std.int (MAX, MIN)
1.checked_sub(1) # => Option.Some(0)
MIN.checked_sub(1) # => Option.None
clone
Show source codeHide source code
fn pub inline clone -> Int {
self
}
fn pub inline clone -> Int
Creates a clone of self
.
The returned value is an owned value that is the same type as the receiver
of this method. For example, cloning a ref Array[Int]
results in a
Array[Int]
, not another ref Array[Int]
.
cmp
Show source codeHide source code
fn pub inline cmp(other: ref Int) -> Ordering {
if self > other {
Ordering.Greater
} else if self < other {
Ordering.Less
} else {
Ordering.Equal
}
}
fn pub inline cmp(other: Int) -> Ordering
Returns the ordering between self
and the given argument.
The returned value should be as follows:
a == b
:Ordering.Equal
a > b
:Ordering.Greater
a < b
:Ordering.Less
digits
Show source codeHide source code
fn pub digits -> Int {
if self == 0 { return 1 }
let mut digits = 0
let mut number = absolute
while number > 0 {
number /= 10
digits += 1
}
digits
}
fn pub digits -> Int
Returns the number of digits of self
.
Examples
0.digits # => 1
10.digits # => 2
100.digits # => 3
-100.digits # => 3
fmt
Show source codeHide source code
fn pub fmt(formatter: mut Formatter) {
formatter.write(to_string)
}
fn pub fmt(formatter: mut Formatter)
Formats self
in a human-readable format for debugging purposes.
format
Show source codeHide source code
fn pub format(format: ref Format) -> String {
let base = format.to_base
match self {
case 0 -> return '0'
# MIN can't be turned positive using absolute(), so we have to handle
# these cases explicitly.
case MIN if base == 2 -> {
return '-1000000000000000000000000000000000000000000000000000000000000000'
}
case MIN if base == 10 -> return '-9223372036854775808'
case MIN if base == 16 -> return '-8000000000000000'
case _ -> {}
}
let alphabet = '0123456789abcdef'
let bytes = ByteArray.new
let mut int = absolute
while int > 0 {
bytes.push(alphabet.get(int % base).or_panic)
int /= base
}
if self < 0 { bytes.push(0x2D) }
bytes.reverse
bytes.into_string
}
fn pub format(format: Format) -> String
Formats self
as a String
in the given format.
Examples
Formatting an Int
as binary number:
import std.int (Format)
3.format(Format.Binary) # => '11'
-1.format(Format.Binary) # => '-11'
Formatting an Int
as a a decimal number:
123.format(Format.Decimal) # => '123'
123.format(Format.Hex) # => '7b'
Formatting an Int
as a hexadecimal number:
-123.format(Format.Hex) # => '-7b'
hash
Show source codeHide source code
fn pub inline hash[H: mut + Hasher](hasher: mut H) {
hasher.write(clone)
}
fn pub inline hash[H: mut + Hasher](hasher: mut H: mut)
Writes the hash for self
into the given Hasher
.
leading_ones
Show source codeHide source code
fn pub inline leading_ones -> Int {
_INKO.int_leading_zeros(not)
}
fn pub inline leading_ones -> Int
Returns the number of leading (most significant) ones in the binary
representation of self
.
Examples
-1.leading_ones # => 64
-2.leading_ones # => 63
leading_zeros
Show source codeHide source code
fn pub inline leading_zeros -> Int {
_INKO.int_leading_zeros(self)
}
fn pub inline leading_zeros -> Int
Returns the number of leading (most significant) zeros in the binary
representation of self
.
Examples
0.leading_zeros # => 64
1000.leading_zeros # => 54
nearest_power_of_two
Show source codeHide source code
fn pub nearest_power_of_two -> Int {
if self <= 0 { return 0 }
let mut rounded = clone
rounded -= 1
rounded |= rounded >> 1
rounded |= rounded >> 2
rounded |= rounded >> 4
rounded |= rounded >> 8
rounded |= rounded >> 16
rounded |= rounded >> 32
rounded += 1
rounded
}
fn pub nearest_power_of_two -> Int
Rounds self
to the nearest power of two.
If self <= 0
, this method returns zero.
Examples
0.nearest_power_of_two # => 0
1.nearest_power_of_two # => 1
2.nearest_power_of_two # => 2
3.nearest_power_of_two # => 4
not
Show source codeHide source code
fn pub inline not -> Int {
_INKO.int_bit_not(self)
}
fn pub inline not -> Int
Returns the result of performing a bitwise NOT
on self
.
As Inko doesn't support unary operators besides not
(which only supports
booleans), this is just a regular method.
Examples
12.not # => -13
opposite
Show source codeHide source code
fn pub inline opposite -> Int {
0 - self
}
fn pub inline opposite -> Int
Returns a value with the opposite sign of self
.
Examples
-42.opposite # => 42
42.opposite # => -42
rotate_left
Show source codeHide source code
fn pub inline rotate_left(amount: Int) -> Int {
_INKO.int_rotate_left(self, amount)
}
fn pub inline rotate_left(amount: Int) -> Int
Shifts the bits to the left, wrapping the truncated bits to the end of the resulting integer.
Examples
0xaa00000000006e1.rotate_left(12) # => 0x6e10aa
rotate_right
Show source codeHide source code
fn pub inline rotate_right(amount: Int) -> Int {
_INKO.int_rotate_right(self, amount)
}
fn pub inline rotate_right(amount: Int) -> Int
Shifts the bits to the right, wrapping the truncated bits to the end of the resulting integer.
Examples
0x6e10aa.rotate_right(12) # => 0xaa00000000006e1
swap_bytes
Show source codeHide source code
fn pub inline swap_bytes -> Int {
_INKO.int_swap_bytes(self)
}
fn pub inline swap_bytes -> Int
Returns a copy of self
with the byte order reversed.
Examples
12345.swap_bytes # => 4120793659044003840
4120793659044003840.swap_bytes # => 12345
times
Show source codeHide source code
fn pub times(block: fn (Int)) {
let mut index = 0
while index < self {
block.call(index)
index += 1
}
}
fn pub times(block: fn (Int))
Calls the supplied closure self
times.
Examples
4.times fn (i) {
i # => 0, 1, 2, 3
}
to
Show source codeHide source code
fn pub inline to(other: Int) -> InclusiveRange {
InclusiveRange.new(clone, other)
}
fn pub inline to(other: Int) -> InclusiveRange
Returns a Range
from self
up to and including other
.
to_float
Show source codeHide source code
fn pub inline to_float -> Float {
self as Float
}
fn pub inline to_float -> Float
Converts self
to a Float
to_int
Show source codeHide source code
fn pub inline to_int -> Int {
clone
}
fn pub inline to_int -> Int
Converts self
to a Int
to_string
Show source codeHide source code
fn pub to_string -> String {
format(Format.Decimal)
}
fn pub to_string -> String
Converts self
to a String
.
trailing_ones
Show source codeHide source code
fn pub inline trailing_ones -> Int {
_INKO.int_trailing_zeros(not)
}
fn pub inline trailing_ones -> Int
Returns the number of trailing (least significant) ones in the binary
representation of self
.
Examples
1.trailing_ones # => 1
11.trailing_ones # => 2
trailing_zeros
Show source codeHide source code
fn pub inline trailing_zeros -> Int {
_INKO.int_trailing_zeros(self)
}
fn pub inline trailing_zeros -> Int
Returns the number of trailing (least significant) zeros in the binary
representation of self
.
Examples
0.trailing_zeros # => 0
1000.trailing_zeros # => 3
until
Show source codeHide source code
fn pub inline until(other: Int) -> ExclusiveRange {
ExclusiveRange.new(clone, other)
}
fn pub inline until(other: Int) -> ExclusiveRange
Returns a Range
from self
up to but excluding other
.
wrapping_add
Show source codeHide source code
fn pub inline wrapping_add(other: Int) -> Int {
_INKO.int_wrapping_add(self, other)
}
fn pub inline wrapping_add(other: Int) -> Int
Adds other
to self
, wrapping around when overflowing.
Examples
import std.int (MAX, MIN)
1.wrapping_add(1) # => 2
MAX.wrapping_add(1) # => MIN
wrapping_mul
Show source codeHide source code
fn pub inline wrapping_mul(other: Int) -> Int {
_INKO.int_wrapping_mul(self, other)
}
fn pub inline wrapping_mul(other: Int) -> Int
Multiplies other
with self
, wrapping around when overflowing.
Examples
import std.int (MAX)
1.wrapping_mul(2) # => 2
MAX.wrapping_mul(2) # => -2
wrapping_sub
Show source codeHide source code
fn pub inline wrapping_sub(other: Int) -> Int {
_INKO.int_wrapping_sub(self, other)
}
fn pub inline wrapping_sub(other: Int) -> Int
Subtracts other
from self
, wrapping around when overflowing.
Examples
import std.int (MAX, MIN)
1.wrapping_sub(1) # => 0
MIN.wrapping_sub(1) # => MAX
|
Show source codeHide source code
fn pub inline |(other: ref Int) -> Int {
_INKO.int_bit_or(self, other)
}
fn pub inline |(other: Int) -> Int
Returns the result of a bitwise OR with self
and the given object.
Implemented traits
Clone
impl Clone for Int
Compare
impl Compare for Int
Equal
impl Equal for Int
ToFloat
impl ToFloat for Int
Format
impl Format for Int
Hash
impl Hash for Int
ToInt
impl ToInt for Int
Add
impl Add[Int, Int] for Int
BitAnd
impl BitAnd[Int, Int] for Int
BitOr
impl BitOr[Int, Int] for Int
BitXor
impl BitXor[Int, Int] for Int
Divide
impl Divide[Int, Int] for Int
Modulo
impl Modulo[Int, Int] for Int
Multiply
impl Multiply[Int, Int] for Int
Power
impl Power[Int, Int] for Int
ShiftLeft
impl ShiftLeft[Int, Int] for Int
ShiftRight
impl ShiftRight[Int, Int] for Int
Subtract
impl Subtract[Int, Int] for Int
UnsignedShiftRight
impl UnsignedShiftRight[Int, Int] for Int
ToString
impl ToString for Int