u16.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 u16
#
# Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------
# u16 -- 16-bit unsigned integer values
#
public u16(public val u16) : num.wrap_around, has_interval, java_primitive is
# overflow checking
# would negation cause an overflow?
redef wrapped_on_neg => !is_zero
# would addition + other cause an overflow or underflow?
public fixed redef overflow_on_add (other u16) => u16.max -° val < other
public fixed redef underflow_on_add(other u16) => false
# would subtraction - other cause an overflow or underflow?
public fixed redef overflow_on_sub (other u16) => false
public fixed redef underflow_on_sub(other u16) => val < other
# would multiplication * other cause an overflow or underflow?
public fixed redef overflow_on_mul (other u16) => as_i32 *° other.as_i32 > u16.max.as_i32
public fixed redef underflow_on_mul(other u16) => false
# neg, add, sub, mul with wrap-around semantics
public fixed redef prefix -° u16 => intrinsic
public fixed redef infix +° (other u16) u16 => intrinsic
public fixed redef infix -° (other u16) u16 => intrinsic
public fixed redef infix *° (other u16) u16 => intrinsic
# division and remainder with check for div-by-zero
public fixed redef infix / (other u16)
pre else
# NYI: #3051 precondition inheritance does not work yet
# remove this redundant precondition once #3051 is fixed
safety: other != 0
=> div other
public fixed redef infix % (other u16)
pre else
# NYI: #3051 precondition inheritance does not work yet
# remove this redundant precondition once #3051 is fixed
safety: other != 0
=> mod other
# division and remainder with crash in case of div-by-zero
div (other u16) u16 => intrinsic
mod (other u16) u16 => intrinsic
# bitwise and, or and xor operations
public fixed redef infix & (other u16) u16 => intrinsic
public fixed redef infix | (other u16) u16 => intrinsic
public fixed redef infix ^ (other u16) u16 => intrinsic
# shift operations (unsigned)
public fixed redef infix >> (other u16) u16 => intrinsic
public fixed redef infix << (other u16) u16 => intrinsic
# does this u16 fit into an u8?
#
public fixed redef fits_in_u8 => val ≤ u8.max.as_u16
public as_i8 i8
pre
debug: val ≤ i8.max.as_u16
=>
cast_to_i16.as_i8
public as_i16 i16
pre
debug: val ≤ i16.max.as_u16
=>
cast_to_i16
public as_i32 i32 => intrinsic
public as_i64 => val.as_i32.as_i64
public as_i128 => val.as_i32.as_i128
public redef as_u8 => low8bits
public as_u32 => val.as_i32.as_u32
public as_u64 => val.as_i32.as_u64
public as_u128 => val.as_i32.as_u128
public as_int => int as_i64
public redef low8bits u8 => intrinsic
public cast_to_i16 i16 => intrinsic
# create hash code from this number
public redef type.hash_code(a u16.this) u64 =>
hash a.as_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 u16 =>
(v, s) := (val, u16 0 )
(v1, s1) := if (v < 0x100) (v , s ) else (v >> 8, s + 8)
(v2, s2) := if (v1 < 0x10) (v1, s1) else (v1 >> 4, s1 + 4)
(v3, s3) := if (v2 < 4) (v2, s2) else (v2 >> 2, s2 + 2)
(v4, s4) := if (v3 < 2) (v3, s3) else (v3 >> 1, s3 + 1)
v4 << s4
# count the number of trailing zeros in this integer.
#
public trailing_zeros i32 =>
(v, s) := (val, 0)
(v1, s1) := if (v & 0xff) != 0 then (v , s ) else (v >> 8, s + 8)
(v2, s2) := if (v1 & 0xf) != 0 then (v1, s1) else (v1 >> 4, s1 + 4)
(v3, s3) := if (v2 & 3) != 0 then (v2, s2) else (v2 >> 2, s2 + 2)
(v4, s4) := if (v3 & 1) != 0 then (v3, s3) else (v3 >> 1, s3 + 1)
if (v4 & 1) != 0 then s4 else 16
# count the number of 1 bits in the binary representation of this
# integer.
#
public redef ones_count i32 =>
v := val.as_i32
m := v & 0xaaaa; v1 := v - m + (m >> 1)
m1 := v1 & 0xcccc; v2 := v1 - m1 + (m1 >> 2)
m2 := v2 & 0xf0f0; v3 := v2 - m2 + (m2 >> 4)
(v3 + (v3 >> 8)) & 0x1f
# -----------------------------------------------------------------------
#
# type features:
# identity element for 'infix +'
#
fixed redef type.zero u16 => 0
# identity element for 'infix *'
#
fixed redef type.one u16 => 1
# equality
#
public fixed redef type.equality(a, b u16) bool => intrinsic
# total order
#
public fixed redef type.lteq(a, b u16) bool => intrinsic
# returns the number in whose bit representation all bits are ones
fixed redef type.all_bits_set => u16 0xffff
# minimum
#
public fixed redef type.min => u16 0
# maximum
#
public fixed redef type.max => u16 0xffff
last changed: 2025-01-23