diff --git a/builtin/builtin.mbti b/builtin/builtin.mbti index a2eff4a1a..f78aacc91 100644 --- a/builtin/builtin.mbti +++ b/builtin/builtin.mbti @@ -433,9 +433,11 @@ impl Byte { op_sub(Byte, Byte) -> Byte to_float(Byte) -> Float to_int(Byte) -> Int + to_int16(Byte) -> Int16 to_int64(Byte) -> Int64 to_string(Byte) -> String to_uint(Byte) -> UInt + to_uint16(Byte) -> UInt16 } @@ -485,16 +487,26 @@ impl Int { to_byte(Int) -> Byte to_double(Int) -> Double to_float(Int) -> Float + to_int16(Int) -> Int16 to_int64(Int) -> Int64 to_json(Int) -> Json to_string(Int) -> String to_uint(Int) -> UInt //deprecated + to_uint16(Int) -> UInt16 to_uint64(Int) -> UInt64 until(Int, Int, step~ : Int = .., inclusive~ : Bool = ..) -> Iter[Int] upto(Int, Int, inclusive~ : Bool = ..) -> Iter[Int] //deprecated } +impl Int16 { + to_byte(Int16) -> Byte + to_int(Int16) -> Int + to_int64(Int16) -> Int64 + to_string(Int16) -> String +} + + impl Int64 { asr(Int64, Int) -> Int64 //deprecated clz(Int64) -> Int @@ -525,8 +537,10 @@ impl Int64 { to_double(Int64) -> Double to_float(Int64) -> Float to_int(Int64) -> Int + to_int16(Int64) -> Int16 to_json(Int64) -> Json to_string(Int64) -> String + to_uint16(Int64) -> UInt16 to_uint64(Int64) -> UInt64 //deprecated until(Int64, Int64, step~ : Int64 = .., inclusive~ : Bool = ..) -> Iter[Int64] upto(Int64, Int64, inclusive~ : Bool = ..) -> Iter[Int64] //deprecated @@ -567,6 +581,14 @@ impl UInt { } +impl UInt16 { + to_byte(UInt16) -> Byte + to_int(UInt16) -> Int + to_int64(UInt16) -> Int64 + to_string(UInt16) -> String +} + + impl UInt64 { clz(UInt64) -> Int compare(UInt64, UInt64) -> Int @@ -870,8 +892,10 @@ impl Show for Bool impl Show for Byte impl Show for Char impl Show for Int +impl Show for Int16 impl Show for Int64 impl Show for UInt +impl Show for UInt16 impl Show for UInt64 impl Show for String impl[X : Show] Show for X? diff --git a/builtin/console.mbt b/builtin/console.mbt index e84ffdd68..e3cbfffbe 100644 --- a/builtin/console.mbt +++ b/builtin/console.mbt @@ -147,6 +147,16 @@ pub fn UInt64::to_string(self : UInt64) -> String { buf.to_string() } +///| +pub fn Int16::to_string(self : Int16) -> String { + self.to_int().to_string() +} + +///| +pub fn UInt16::to_string(self : UInt16) -> String { + self.to_int().to_string() +} + ///| /// @coverage.skip pub fn op_lt[T : Compare](self_ : T, other : T) -> Bool { diff --git a/builtin/int64_js.mbt b/builtin/int64_js.mbt index 1060c3d34..85fb02957 100644 --- a/builtin/int64_js.mbt +++ b/builtin/int64_js.mbt @@ -546,6 +546,16 @@ pub fn Int64::to_byte(self : Int64) -> Byte { MyInt64::from_int64(self).to_int().to_byte() } +///| +pub fn Int64::to_int16(self : Int64) -> Int16 { + MyInt64::from_int64(self).to_int().to_int16() +} + +///| +pub fn Int64::to_uint16(self : Int64) -> UInt16 { + MyInt64::from_int64(self).to_int().to_uint16() +} + ///| pub fn UInt64::extend_uint(value : UInt) -> UInt64 { MyInt64::extend_i32_u(value.reinterpret_as_int()).to_uint64() @@ -566,6 +576,16 @@ pub fn Int::to_int64(self : Int) -> Int64 { MyInt64::from_int(self).to_int64() } +///| +pub fn Int16::to_int64(self : Int16) -> Int64 { + MyInt64::from_int(self.to_int()).to_int64() +} + +///| +pub fn UInt16::to_int64(self : UInt16) -> Int64 { + MyInt64::from_int(self.to_int()).to_int64() +} + ///| /// @alert deprecated "Use `reinterpret_as_int64` instead" /// @coverage.skip diff --git a/builtin/int64_nonjs.mbt b/builtin/int64_nonjs.mbt index 00fdce004..262f0838e 100644 --- a/builtin/int64_nonjs.mbt +++ b/builtin/int64_nonjs.mbt @@ -106,6 +106,12 @@ pub fn UInt64::reinterpret_as_double(self : UInt64) -> Double = "%i64_to_f64_rei ///| pub fn Int64::to_byte(self : Int64) -> Byte = "%i64_to_byte" +///| +pub fn Int64::to_int16(self : Int64) -> Int16 = "%i64_to_i16" + +///| +pub fn Int64::to_uint16(self : Int64) -> UInt16 = "%i64_to_u16" + ///| pub fn UInt64::trunc_double(val : Double) -> UInt64 = "%f64.to_u64" @@ -118,6 +124,12 @@ pub fn UInt64::extend_uint(val : UInt) -> UInt64 = "%u32.to_u64" ///| pub fn Int::to_int64(self : Int) -> Int64 = "%i32_to_i64" +///| +pub fn Int16::to_int64(self : Int16) -> Int64 = "%i16_to_i64" + +///| +pub fn UInt16::to_int64(self : UInt16) -> Int64 = "%u16_to_i64" + ///| /// @alert deprecated "Use `reinterpret_as_int64` instead" /// @coverage.skip diff --git a/builtin/intrinsics.mbt b/builtin/intrinsics.mbt index b21eadca7..e929f1630 100644 --- a/builtin/intrinsics.mbt +++ b/builtin/intrinsics.mbt @@ -462,3 +462,27 @@ pub fn Double::to_float(self : Double) -> Float = "%f64.to_f32" ///| pub fn UInt::to_float(self : UInt) -> Float = "%u32.to_f32" + +///| +pub fn Int16::to_int(self : Int16) -> Int = "%i16_to_i32" + +///| +pub fn Int16::to_byte(self : Int16) -> Byte = "%i16_to_byte" + +///| +pub fn Int::to_int16(self : Int) -> Int16 = "%i32_to_i16" + +///| +pub fn Byte::to_int16(self : Byte) -> Int16 = "%byte_to_i16" + +///| +pub fn UInt16::to_int(self : UInt16) -> Int = "%u16_to_i32" + +///| +pub fn UInt16::to_byte(self : UInt16) -> Byte = "%u16_to_byte" + +///| +pub fn Int::to_uint16(self : Int) -> UInt16 = "%i32_to_u16" + +///| +pub fn Byte::to_uint16(self : Byte) -> UInt16 = "%byte_to_u16" diff --git a/builtin/show.mbt b/builtin/show.mbt index a207b7558..fe6003248 100644 --- a/builtin/show.mbt +++ b/builtin/show.mbt @@ -45,6 +45,16 @@ pub impl Show for Byte with output(self, logger) { logger.write_string(self.to_string()) } +///| +pub impl Show for Int16 with output(self, logger) { + logger.write_string(self.to_string()) +} + +///| +pub impl Show for UInt16 with output(self, logger) { + logger.write_string(self.to_string()) +} + ///| pub impl Show for Bytes with output(self, logger) { fn to_hex_digit(i : Int) -> Char { diff --git a/int16/int16.mbt b/int16/int16.mbt new file mode 100644 index 000000000..7227eafee --- /dev/null +++ b/int16/int16.mbt @@ -0,0 +1,51 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +pub fn op_add(self : Int16, that : Int16) -> Int16 { + (self.to_int() + that.to_int()).to_int16() +} + +///| +pub fn op_sub(self : Int16, that : Int16) -> Int16 { + (self.to_int() - that.to_int()).to_int16() +} + +///| +pub fn op_mul(self : Int16, that : Int16) -> Int16 { + (self.to_int() * that.to_int()).to_int16() +} + +///| +pub fn op_div(self : Int16, that : Int16) -> Int16 { + (self.to_int() / that.to_int()).to_int16() +} + +///| +pub fn op_equal(self : Int16, that : Int16) -> Bool { + self.to_int() == that.to_int() +} + +///| +pub fn compare(self : Int16, that : Int16) -> Int { + self.to_int().compare(that.to_int()) +} + +///| +pub impl Hash for Int16 with hash(self) { self.to_int() } + +///| +pub impl Hash for Int16 with hash_combine(self, hasher) { + hasher.combine_int(self.to_int()) +} diff --git a/int16/int16.mbti b/int16/int16.mbti new file mode 100644 index 000000000..a834be4ef --- /dev/null +++ b/int16/int16.mbti @@ -0,0 +1,20 @@ +package moonbitlang/core/int16 + +// Values + +// Types and methods + + +impl Int16 { + compare(Int16, Int16) -> Int + op_add(Int16, Int16) -> Int16 + op_div(Int16, Int16) -> Int16 + op_equal(Int16, Int16) -> Bool + op_mul(Int16, Int16) -> Int16 + op_sub(Int16, Int16) -> Int16 +} + +// Type aliases + +// Traits + diff --git a/int16/int16_test.mbt b/int16/int16_test.mbt new file mode 100644 index 000000000..94e590872 --- /dev/null +++ b/int16/int16_test.mbt @@ -0,0 +1,193 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +test "Int16::to_int" { + inspect!(Int16::to_int(0), content="0") + inspect!(Int16::to_int(123), content="123") + inspect!(Int16::to_int(-123), content="-123") + inspect!(Int16::to_int(32767), content="32767") + inspect!(Int16::to_int(-32768), content="-32768") +} + +test "Int16::from_int" { + inspect!(Int::to_int16(0), content="0") + inspect!(Int::to_int16(123), content="123") + inspect!(Int::to_int16(-123), content="-123") + inspect!(Int::to_int16(32767), content="32767") + inspect!(Int::to_int16(-32768), content="-32768") + inspect!(Int::to_int16(32768), content="-32768") + inspect!(Int::to_int16(-32769), content="32767") + inspect!(Int::to_int16(65535), content="-1") + inspect!(Int::to_int16(-65536), content="0") + inspect!(Int::to_int16(65536), content="0") +} + +test "Int16::to_byte" { + inspect!(Int16::to_byte(0), content="b'\\x00'") + inspect!(Int16::to_byte(123), content="b'\\x7B'") + inspect!(Int16::to_byte(-123), content="b'\\x85'") + inspect!(Int16::to_byte(255), content="b'\\xFF'") + inspect!(Int16::to_byte(-256), content="b'\\x00'") + inspect!(Int16::to_byte(256), content="b'\\x00'") + inspect!(Int16::to_byte(-257), content="b'\\xFF'") +} + +test "Int16::from_byte" { + inspect!(Byte::to_int16(0), content="0") + inspect!(Byte::to_int16(123), content="123") + inspect!(Byte::to_int16(255), content="255") +} + +test "Int16::to_int64" { + inspect!(Int16::to_int64(0), content="0") + inspect!(Int16::to_int64(123), content="123") + inspect!(Int16::to_int64(-123), content="-123") + inspect!(Int16::to_int64(32767), content="32767") + inspect!(Int16::to_int64(-32768), content="-32768") +} + +test "Int16::from_int64" { + inspect!(Int::to_int16(0), content="0") + inspect!(Int::to_int16(123), content="123") + inspect!(Int::to_int16(-123), content="-123") + inspect!(Int::to_int16(32767), content="32767") + inspect!(Int::to_int16(-32768), content="-32768") + inspect!(Int::to_int16(32768), content="-32768") + inspect!(Int::to_int16(-32769), content="32767") + inspect!(Int::to_int16(65535), content="-1") + inspect!(Int::to_int16(-65536), content="0") + inspect!(Int::to_int16(65536), content="0") +} + +test "Int16::op_add" { + fn add(a : Int16, b : Int16) -> Int16 { + a + b + } + + inspect!(add(1, 2), content="3") + inspect!(add(0, 0), content="0") + inspect!(add(32767, 1), content="-32768") // Overflow case + inspect!(add(-32768, -1), content="32767") // Underflow case + inspect!(add(16384, 16384), content="-32768") // Large positive numbers + inspect!(add(-16384, -16384), content="-32768") // Large negative numbers + inspect!(add(10000, -10000), content="0") // Positive + negative + inspect!(add(-10000, 10000), content="0") // Negative + positive + inspect!(add(32767, -32768), content="-1") // Max + min + inspect!(add(-32768, 32767), content="-1") // Min + max + inspect!(add(16000, 16000), content="32000") // Overflow in middle range + inspect!(add(-16000, -16000), content="-32000") // Underflow in middle range +} + +test "Int16::op_sub" { + fn sub(a : Int16, b : Int16) -> Int16 { + a - b + } + + inspect!(sub(3, 2), content="1") + inspect!(sub(0, 0), content="0") + inspect!(sub(-32768, 1), content="32767") // Underflow case + inspect!(sub(32767, -1), content="-32768") // Overflow case + inspect!(sub(16384, -16384), content="-32768") // Large positive difference + inspect!(sub(-16384, 16384), content="-32768") // Large negative difference + inspect!(sub(10000, 10000), content="0") // Same numbers + inspect!(sub(-10000, -10000), content="0") // Same negative numbers + inspect!(sub(32767, 32767), content="0") // Max - max + inspect!(sub(-32768, -32768), content="0") // Min - min + inspect!(sub(0, 32767), content="-32767") // Zero - max + inspect!(sub(0, -32768), content="-32768") // Zero - min +} + +test "Int16::op_mul" { + fn mul(a : Int16, b : Int16) -> Int16 { + a * b + } + + inspect!(mul(0, 0), content="0") + inspect!(mul(1, 1), content="1") + inspect!(mul(-1, -1), content="1") + inspect!(mul(-1, 1), content="-1") + inspect!(mul(2, 3), content="6") + inspect!(mul(-2, 3), content="-6") + inspect!(mul(181, 181), content="32761") // Near max positive result + inspect!(mul(182, 182), content="-32412") // Overflow case + inspect!(mul(-181, -181), content="32761") // Near max from negatives + inspect!(mul(-182, 181), content="32594") // Mixed signs overflow + inspect!(mul(16384, 2), content="-32768") // Power of 2 overflow + inspect!(mul(-32768, 1), content="-32768") // Min value * 1 + inspect!(mul(32767, 1), content="32767") // Max value * 1 + inspect!(mul(16383, 2), content="32766") // Just below overflow +} + +test "Int16::op_div" { + fn div(a : Int16, b : Int16) -> Int16 { + a / b + } + + inspect!(div(6, 2), content="3") + inspect!(div(0, 1), content="0") + inspect!(div(1, 1), content="1") + inspect!(div(-1, -1), content="1") + inspect!(div(-1, 1), content="-1") + inspect!(div(32767, 1), content="32767") // Max value / 1 + inspect!(div(-32768, 1), content="-32768") // Min value / 1 + inspect!(div(-32768, -1), content="-32768") // Min value / -1 (overflow) + inspect!(div(32767, -1), content="-32767") // Max value / -1 + inspect!(div(12345, 123), content="100") // Larger numbers + inspect!(div(-12345, 123), content="-100") // Negative dividend + inspect!(div(12345, -123), content="-100") // Negative divisor + inspect!(div(-12345, -123), content="100") // Both negative + inspect!(div(32766, 2), content="16383") // Even division near max + inspect!(div(-32768, 2), content="-16384") // Even division of min +} + +test "Int16::compare" { + inspect!(Int16::compare(1, 2), content="-1") + inspect!(Int16::compare(2, 1), content="1") + inspect!(Int16::compare(1, 1), content="0") + inspect!(Int16::compare(-1, 1), content="-1") + inspect!(Int16::compare(1, -1), content="1") + inspect!(Int16::compare(-1, -1), content="0") + inspect!(Int16::compare(-2, -1), content="-1") + inspect!(Int16::compare(-1, -2), content="1") + inspect!(Int16::compare(32767, 32766), content="1") // Max value comparison + inspect!(Int16::compare(32766, 32767), content="-1") + inspect!(Int16::compare(32767, 32767), content="0") // Max value equals + inspect!(Int16::compare(-32768, -32767), content="-1") // Min value comparison + inspect!(Int16::compare(-32767, -32768), content="1") + inspect!(Int16::compare(-32768, -32768), content="0") // Min value equals + inspect!(Int16::compare(-32768, 32767), content="-1") // Min vs Max + inspect!(Int16::compare(32767, -32768), content="1") // Max vs Min + inspect!(Int16::compare(0, 32767), content="-1") // Zero vs Max + inspect!(Int16::compare(0, -32768), content="1") // Zero vs Min + inspect!(Int16::compare(0, 0), content="0") // Zero equals +} + +test "Int16::hash" { + inspect!(Int16::hash(1), content="1") + inspect!(Int16::hash(-1), content="-1") + inspect!(Int16::hash(32767), content="32767") + inspect!(Int16::hash(-32768), content="-32768") + inspect!(Int16::hash(0), content="0") + inspect!(Int16::hash(12345), content="12345") + inspect!(Int16::hash(-12345), content="-12345") +} + +test "Int16::op_equal" { + inspect!(Int16::op_equal(1, 2), content="false") + inspect!(Int16::op_equal(2, 1), content="false") + inspect!(Int16::op_equal(1, 1), content="true") + inspect!(Int16::op_equal(-1, 1), content="false") + inspect!(Int16::op_equal(1, -1), content="false") + inspect!(Int16::op_equal(-1, -1), content="true") +} diff --git a/int16/moon.pkg.json b/int16/moon.pkg.json new file mode 100644 index 000000000..56cd56a09 --- /dev/null +++ b/int16/moon.pkg.json @@ -0,0 +1,3 @@ +{ + "import": ["moonbitlang/core/builtin"] +} diff --git a/uint16/moon.pkg.json b/uint16/moon.pkg.json new file mode 100644 index 000000000..56cd56a09 --- /dev/null +++ b/uint16/moon.pkg.json @@ -0,0 +1,3 @@ +{ + "import": ["moonbitlang/core/builtin"] +} diff --git a/uint16/uint16.mbt b/uint16/uint16.mbt new file mode 100644 index 000000000..12f96be1e --- /dev/null +++ b/uint16/uint16.mbt @@ -0,0 +1,51 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +pub fn op_add(self : UInt16, that : UInt16) -> UInt16 { + (self.to_int() + that.to_int()).to_uint16() +} + +///| +pub fn op_sub(self : UInt16, that : UInt16) -> UInt16 { + (self.to_int() - that.to_int()).to_uint16() +} + +///| +pub fn op_mul(self : UInt16, that : UInt16) -> UInt16 { + (self.to_int() * that.to_int()).to_uint16() +} + +///| +pub fn op_div(self : UInt16, that : UInt16) -> UInt16 { + (self.to_int() / that.to_int()).to_uint16() +} + +///| +pub fn op_equal(self : UInt16, that : UInt16) -> Bool { + self.to_int() == that.to_int() +} + +///| +pub fn compare(self : UInt16, that : UInt16) -> Int { + self.to_int().compare(that.to_int()) +} + +///| +pub impl Hash for UInt16 with hash(self) { self.to_int() } + +///| +pub impl Hash for UInt16 with hash_combine(self, hasher) { + hasher.combine_int(self.to_int()) +} diff --git a/uint16/uint16.mbti b/uint16/uint16.mbti new file mode 100644 index 000000000..748de5bec --- /dev/null +++ b/uint16/uint16.mbti @@ -0,0 +1,20 @@ +package moonbitlang/core/uint16 + +// Values + +// Types and methods + + +impl UInt16 { + compare(UInt16, UInt16) -> Int + op_add(UInt16, UInt16) -> UInt16 + op_div(UInt16, UInt16) -> UInt16 + op_equal(UInt16, UInt16) -> Bool + op_mul(UInt16, UInt16) -> UInt16 + op_sub(UInt16, UInt16) -> UInt16 +} + +// Type aliases + +// Traits + diff --git a/uint16/uint16_test.mbt b/uint16/uint16_test.mbt new file mode 100644 index 000000000..70fa84778 --- /dev/null +++ b/uint16/uint16_test.mbt @@ -0,0 +1,176 @@ +// Copyright 2024 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +test "UInt16::to_int" { + inspect!(UInt16::to_int(0), content="0") + inspect!(UInt16::to_int(123), content="123") + inspect!(UInt16::to_int(65535), content="65535") +} + +test "UInt16::from_int" { + inspect!(Int::to_uint16(0), content="0") + inspect!(Int::to_uint16(123), content="123") + inspect!(Int::to_uint16(65535), content="65535") + inspect!(Int::to_uint16(-1), content="65535") + inspect!(Int::to_uint16(-123), content="65413") + inspect!(Int::to_uint16(65536), content="0") + inspect!(Int::to_uint16(65537), content="1") + inspect!(Int::to_uint16(131071), content="65535") + inspect!(Int::to_uint16(-65536), content="0") + inspect!(Int::to_uint16(-65537), content="65535") +} + +test "UInt16::to_byte" { + inspect!(UInt16::to_byte(0), content="b'\\x00'") + inspect!(UInt16::to_byte(123), content="b'\\x7B'") + inspect!(UInt16::to_byte(65535), content="b'\\xFF'") +} + +test "UInt16::from_byte" { + inspect!(Byte::to_uint16(0), content="0") + inspect!(Byte::to_uint16(123), content="123") + inspect!(Byte::to_uint16(255), content="255") +} + +test "UInt16::to_int64" { + inspect!(UInt16::to_int64(0), content="0") + inspect!(UInt16::to_int64(123), content="123") + inspect!(UInt16::to_int64(65535), content="65535") +} + +test "UInt16::from_int64" { + inspect!(Int::to_uint16(0), content="0") + inspect!(Int::to_uint16(123), content="123") + inspect!(Int::to_uint16(65535), content="65535") + inspect!(Int::to_uint16(-1), content="65535") + inspect!(Int::to_uint16(-123), content="65413") + inspect!(Int::to_uint16(65536), content="0") + inspect!(Int::to_uint16(65537), content="1") + inspect!(Int::to_uint16(131071), content="65535") + inspect!(Int::to_uint16(-65536), content="0") + inspect!(Int::to_uint16(-65537), content="65535") + inspect!(Int::to_uint16(1000000), content="16960") // Large positive number wraps around + inspect!(Int::to_uint16(-1000000), content="48576") // Large negative number wraps around + inspect!(Int::to_uint16(32768), content="32768") // Half of max value + inspect!(Int::to_uint16(49152), content="49152") // 3/4 of max value + inspect!(Int::to_uint16(16384), content="16384") // 1/4 of max value +} + +test "UInt16::op_add" { + fn add(a : UInt16, b : UInt16) -> UInt16 { + a + b + } + + inspect!(add(0, 0), content="0") + inspect!(add(1, 1), content="2") + inspect!(add(100, 200), content="300") + inspect!(add(65535, 1), content="0") // Wraps around to 0 + inspect!(add(65535, 2), content="1") // Wraps around to 1 + inspect!(add(32768, 32768), content="0") // Adding two large numbers wraps + inspect!(add(50000, 20000), content="4464") // Overflow case + inspect!(add(65000, 1000), content="464") // Another overflow + inspect!(add(16384, 16384), content="32768") // Adding quarter max values + inspect!(add(0, 65535), content="65535") // Adding 0 to max +} + +test "UInt16::op_sub" { + fn sub(a : UInt16, b : UInt16) -> UInt16 { + a - b + } + + inspect!(sub(0, 0), content="0") + inspect!(sub(2, 1), content="1") + inspect!(sub(300, 200), content="100") + inspect!(sub(0, 1), content="65535") // Underflow wraps to max value + inspect!(sub(0, 2), content="65534") // Underflow wraps to max-1 + inspect!(sub(65535, 65535), content="0") // Max minus itself + inspect!(sub(32768, 16384), content="16384") // Half max minus quarter max + inspect!(sub(1000, 2000), content="64536") // Underflow case + inspect!(sub(50000, 60000), content="55536") // Another underflow + inspect!(sub(65535, 1), content="65534") // Max minus 1 + inspect!(sub(32768, 32768), content="0") // Equal large numbers +} + +test "UInt16::op_mul" { + fn mul(a : UInt16, b : UInt16) -> UInt16 { + a * b + } + + inspect!(mul(0, 0), content="0") + inspect!(mul(1, 1), content="1") + inspect!(mul(2, 3), content="6") + inspect!(mul(100, 100), content="10000") + inspect!(mul(256, 256), content="0") // Overflow wraps to 0 + inspect!(mul(1000, 100), content="34464") // Overflow case + inspect!(mul(65535, 2), content="65534") // Max value * 2 wraps + inspect!(mul(32768, 2), content="0") // Half max * 2 wraps to 0 + inspect!(mul(255, 255), content="65025") // Near max result + inspect!(mul(16384, 4), content="0") // Quarter max * 4 wraps + inspect!(mul(65535, 65535), content="1") // Max * max wraps to 1 +} + +test "UInt16::op_div" { + fn div(a : UInt16, b : UInt16) -> UInt16 { + a / b + } + + inspect!(div(0, 1), content="0") + inspect!(div(1, 1), content="1") + inspect!(div(6, 2), content="3") + inspect!(div(65535, 1), content="65535") // Max value / 1 + inspect!(div(65535, 2), content="32767") // Max value / 2 + inspect!(div(65535, 65535), content="1") // Max value / itself + inspect!(div(32768, 2), content="16384") // Half max / 2 + inspect!(div(60000, 1000), content="60") // Large number division + inspect!(div(65534, 2), content="32767") // Even division near max + inspect!(div(10000, 100), content="100") // Clean division + inspect!(div(65535, 10), content="6553") // Max value / 10 +} + +test "UInt16::compare" { + inspect!(UInt16::compare(1, 2), content="-1") + inspect!(UInt16::compare(2, 1), content="1") + inspect!(UInt16::compare(1, 1), content="0") + inspect!(UInt16::compare(0, 1), content="-1") + inspect!(UInt16::compare(1, 0), content="1") + inspect!(UInt16::compare(0, 0), content="0") + inspect!(UInt16::compare(65535, 65534), content="1") // Max value comparison + inspect!(UInt16::compare(65534, 65535), content="-1") + inspect!(UInt16::compare(65535, 65535), content="0") // Max value equals + inspect!(UInt16::compare(32768, 32767), content="1") // Half max comparison + inspect!(UInt16::compare(32767, 32768), content="-1") + inspect!(UInt16::compare(32768, 32768), content="0") // Half max equals + inspect!(UInt16::compare(0, 65535), content="-1") // Min vs Max + inspect!(UInt16::compare(65535, 0), content="1") // Max vs Min + inspect!(UInt16::compare(1000, 2000), content="-1") // Mid-range values + inspect!(UInt16::compare(2000, 1000), content="1") + inspect!(UInt16::compare(50000, 50000), content="0") // Large equal values + inspect!(UInt16::compare(50000, 40000), content="1") // Large different values + inspect!(UInt16::compare(40000, 50000), content="-1") +} + +test "UInt16::hash" { + inspect!(UInt16::hash(0), content="0") + inspect!(UInt16::hash(123), content="123") + inspect!(UInt16::hash(65535), content="65535") +} + +test "UInt16::op_equal" { + inspect!(UInt16::op_equal(1, 2), content="false") + inspect!(UInt16::op_equal(2, 1), content="false") + inspect!(UInt16::op_equal(1, 1), content="true") + inspect!(UInt16::op_equal(0, 1), content="false") + inspect!(UInt16::op_equal(1, 0), content="false") + inspect!(UInt16::op_equal(0, 0), content="true") +}