Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

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, java_primitive is

  # overflow checking

  # would negation cause an overflow?
  public redef wrapped_on_neg bool => is_min

  # would addition + other cause an overflow or underflow?
  public fixed redef overflow_on_add (other i64) bool => val > 0 && i64.max -° val < other
  public fixed redef underflow_on_add(other i64) bool => val < 0 && i64.min -° val > other

  # would subtraction - other cause an overflow or underflow?
  public fixed redef overflow_on_sub (other i64) bool => val > 0 && val -° i64.max > other
  public fixed redef underflow_on_sub(other i64) bool => val < 0 && val -° i64.min < other

  # would multiplication * other cause an overflow or underflow?
  public fixed redef overflow_on_mul (other i64) bool => if sign *° other.sign ≤ 0 false else (val *° other / other) != val
  public fixed redef underflow_on_mul(other i64) bool => if sign *° other.sign ≥ 0 false else (val *° other / other) != val

  # neg, add, sub, mul with wrap-around semantics
  public fixed redef prefix -° i64 => intrinsic
  public fixed redef infix +° (other i64) i64 => intrinsic
  public fixed redef infix -° (other i64) i64 => intrinsic
  public fixed redef infix *° (other i64) i64 => intrinsic

  # division and remainder with check for div-by-zero
  public fixed redef infix / (other i64) i64 => div other
  public fixed redef infix % (other i64) i64 => mod other

  # division and remainder with crash in case of div-by-zero
  div (other i64) i64 => intrinsic
  mod (other i64) i64 => intrinsic

  # bitwise and, or and xor operations
  public fixed redef infix &  (other i64) i64 => intrinsic
  public fixed redef infix |  (other i64) i64 => intrinsic
  public fixed redef infix ^  (other i64) i64 => intrinsic

  # shift operations (signed)
  public fixed redef infix >> (other i64) i64 => intrinsic
  public fixed redef infix << (other i64) i64 => intrinsic

  # this i64 as an i8
  public as_i8 i8
    pre
      debug: val ≥ i8.min.as_i64
      debug: val ≤ i8.max.as_i64
    =>
      low8bits.as_i8


  # this i64 as an i16
  public as_i16 i16
    pre
      debug: val ≥ i16.min.as_i64
      debug: val ≤ i16.max.as_i64
    =>
      low16bits.as_i16


  # this i64 as an i32
  public as_i32 i32
    pre
      debug: val ≥ i32.min.as_i64
      debug: val ≤ i32.max.as_i64
    =>
      low32bits.cast_to_i32


  # this i64 as an i128
  public as_i128 i128 =>
    i128 (val >> 63) val.cast_to_u64

  # does this i64 fit into an u8?
  #
  public fixed redef fits_in_u8 bool => 0 ≤ val ≤ u8.max.as_i64


  # this i64 as an u8
  #
  public redef as_u8 u8
    post then
      analysis: result.as_i64 = val
  =>
    low8bits


  # this i64 as an u16
  #
  public as_u16 u16
    pre
      debug: val ≥ 0
      debug: val ≤ u16.max.as_i64
    post
      analysis: result.as_i64 = val
  =>
    low16bits


  # this i64 as an u32
  #
  public as_u32 u32
    pre
      debug: val ≥ (i64 0)
      debug: val ≤ u32.max.as_i64
    post
      analysis:  result.as_i64 = val
  =>
    low32bits


  # this i64 as an u64
  #
  public as_u64 u64
    pre
      debug: val ≥ 0
    post
      analysis: result.as_i64 = val
  =>
    cast_to_u64


  # this i64 as an u128
  #
  public as_u128 u128
    pre
      debug: val ≥ 0
    post
      analysis:  result.as_i64 = val
  =>
    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 debug: val ≥ 0
  =>
    uint val.as_u64


  # casting bit representation to unsigned
  public redef 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 f32 => as_f64.as_f32


  # create hash code from this number
  public redef 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 redef ones_count i32 =>
    val.cast_to_u64.ones_count


  # -----------------------------------------------------------------------
  #
  # type features:


  # identity element for 'infix +'
  #
  public fixed redef type.zero i64 => 0


  # identity element for 'infix *'
  #
  public fixed redef type.one  i64 => 1


  # equality
  #
  public fixed redef type.equality(a, b i64) bool => intrinsic


  # total order
  #
  public fixed redef type.lteq(a, b i64) bool => intrinsic


  # returns the number in whose bit representation all bits are ones
  public fixed redef type.all_bits_set i64 => i64 -1


  # minimum
  #
  public fixed redef type.min i64 => i64 -0x_8000_0000_0000_0000


  # maximum
  #
  public fixed redef type.max i64 => i64 0x_7fff_ffff_ffff_ffff

last changed: 2025-06-17