i64.fz
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature i64
#
# Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------
# i64 -- 64-bit signed integer values
#
public i64(public val i64) : num.wrap_around, has_interval is
public thiz => i64.this.val
# overflow checking
# would negation -thiz cause an overflow?
redef wrapped_on_neg => is_min
# would addition thiz + other cause an overflow or underflow?
public fixed overflow_on_add (other i64) => thiz > i64 0 && i64.max -° thiz < other
public fixed underflow_on_add(other i64) => thiz < i64 0 && i64.min -° thiz > other
# would subtraction thiz - other cause an overflow or underflow?
public fixed overflow_on_sub (other i64) => thiz > i64 0 && thiz -° i64.max > other
public fixed underflow_on_sub(other i64) => thiz < i64 0 && thiz -° i64.min < other
# would multiplication thiz * other cause an overflow or underflow?
public fixed overflow_on_mul (other i64) => if sign *° other.sign ≤ 0 false else (thiz *° other / other) != thiz
public fixed underflow_on_mul(other i64) => if sign *° other.sign ≥ 0 false else (thiz *° other / other) != thiz
# neg, add, sub, mul with wrap-around semantics
public fixed prefix -° i64 => intrinsic
public fixed infix +° (other i64) i64 => intrinsic
public fixed infix -° (other i64) i64 => intrinsic
public fixed infix *° (other i64) i64 => intrinsic
# division and remainder with check for div-by-zero
public fixed infix / (other i64)
pre
safety: other != i64 0
=> div other
public fixed infix % (other i64)
pre
safety: other != i64 0
=> mod other
# private division and remainder with crash in case of div-by-zero
private div (other i64) i64 => intrinsic
private mod (other i64) i64 => intrinsic
# bitwise and, or and xor operations
public fixed infix & (other i64) i64 => intrinsic
public fixed infix | (other i64) i64 => intrinsic
public fixed infix ^ (other i64) i64 => intrinsic
# shift operations (signed)
public fixed infix >> (other i64) i64 => intrinsic
public fixed infix << (other i64) i64 => intrinsic
# this i64 as an i8
public as_i8 i8
pre
thiz ≥ i8.min.as_i64
thiz ≤ i8.max.as_i64
=>
low8bits.as_i8
# this i64 as an i16
public as_i16 i16
pre
thiz ≥ i16.min.as_i64
thiz ≤ i16.max.as_i64
=>
low16bits.as_i16
# this i64 as an i32
public as_i32 i32
pre
thiz ≥ i32.min.as_i64
thiz ≤ i32.max.as_i64
=>
low32bits.cast_to_i32
# this i64 as an u8
public as_u8 u8
pre
thiz ≥ (i64 0)
# thiz ≤ u8.max.as_i64
# post
# analysis: result.as_u64 = thiz
=>
low8bits
# this i64 as an u16
public as_u16 u16
pre
thiz ≥ (i64 0)
# thiz ≤ u16.max.as_i64
# post
# analysis: result.as_u64 = thiz
=>
low16bits
# this i64 as an u32
public as_u32 u32
pre
thiz ≥ (i64 0)
# thiz ≤ u32.max.as_i64
# post
# analysis: result.as_i64 = thiz
=>
low32bits
# this i64 as an u64
public as_u64 u64
pre
thiz ≥ (i64 0)
# post
# analysis: result.as_i64 = thiz
=>
cast_to_u64
# this i64 as an u128
public as_u128 u128
pre
thiz ≥ (i64 0)
post
analysis: result.as_i64 = thiz
=>
u128 0 cast_to_u64
# this i64 as an int
public as_int int =>
int val
# this i64 as an uint
public as_uint uint
pre thiz ≥ 0
=>
uint val.as_u64
# casting bit representation to unsigned
public low8bits u8 => cast_to_u64.low8bits
public low16bits u16 => cast_to_u64.low16bits
public low32bits u32 => cast_to_u64.low32bits
public cast_to_u64 u64 => intrinsic
# conversion to float
public as_f64 f64 => intrinsic
public as_f32 => as_f64.as_f32
# create hash code from this number
public type.hash_code(a i64.this) u64 =>
hash a.cast_to_u64
# find the highest 1 bit in this integer and return integer with
# this single bit set or 0 if this is 0.
#
public highest_one_bit i64 =>
val.cast_to_u64.highest_one_bit.cast_to_i64
# count the number of trailing zeros in this integer.
#
public trailing_zeros i32 =>
val.cast_to_u64.trailing_zeros
# count the number of 1 bits in the binary representation of this
# integer.
#
public ones_count i32 =>
val.cast_to_u64.ones_count
# -----------------------------------------------------------------------
#
# type features:
# identity element for 'infix +'
#
fixed type.zero i64 => 0
# identity element for 'infix *'
#
fixed type.one i64 => 1
# equality
#
fixed type.equality(a, b i64) bool => intrinsic_constructor
# total order
#
fixed type.lteq(a, b i64) bool => intrinsic_constructor
# returns the number in whose bit representation all bits are ones
fixed redef type.all_bits_set => i64 -1
# minimum
#
public fixed type.min => i64 -0x_8000_0000_0000_0000
# maximum
#
public fixed type.max => i64 0x_7fff_ffff_ffff_ffff
last changed: 2024-03-07