hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 9f2a23b73fce3f0175de54939ad59655e9414fca
parent d858829e8243c0ff4d3c5c025553450b24036741
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun, 20 Feb 2022 16:56:38 +0100

math: make absi* functions return an unsigned integer

This allows to avoid abs actually returning a negative integer while also
avoiding overflows.

Signed-off-by: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mmath/ints.ha | 93++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 54 insertions(+), 39 deletions(-)

diff --git a/math/ints.ha b/math/ints.ha @@ -1,74 +1,89 @@ use types; // Returns the absolute value of signed integer n. -export fn absi8(n: i8) i8 = { +export fn absi8(n: i8) u8 = { if (n < 0i8) { - return -n; + return -n: u8; } else { - return n; + return n: u8; }; }; // Returns the absolute value of signed integer n. -export fn absi16(n: i16) i16 = { +export fn absi16(n: i16) u16 = { if (n < 0i16) { - return -n; + return -n: u16; } else { - return n; + return n: u16; }; }; // Returns the absolute value of signed integer n. -export fn absi32(n: i32) i32 = { +export fn absi32(n: i32) u32 = { if (n < 0i32) { - return -n; + return -n: u32; } else { - return n; + return n: u32; }; }; // Returns the absolute value of signed integer n. -export fn absi64(n: i64) i64 = { +export fn absi64(n: i64) u64 = { if (n < 0i64) { - return -n; + return -n: u64; } else { - return n; + return n: u64; }; }; // Returns the absolute value of signed integer n. -export fn absi(n: types::integer) i64 = { +export fn absi(n: types::integer) u64 = { match (n) { case let n: i8 => - return (absi8(n): i64); + return absi8(n): u64; case let n: i16 => - return (absi16(n): i64); + return absi16(n): u64; case let n: i32 => - return (absi32(n): i64); + return absi32(n): u64; case let n: i64 => - return (absi64(n): i64); + return absi64(n): u64; case let n: int => - return (absi64(n): i64); + return absi64(n): u64; }; }; @test fn absi() void = { - assert(absi8(2i8) == 2i8); - assert(absi8(-2i8) == 2i8); - assert(absi16(2i16) == 2i16); - assert(absi16(-2i16) == 2i16); - assert(absi32(2i32) == 2i32); - assert(absi32(-2i32) == 2i32); - assert(absi64(2i64) == 2i64); - assert(absi64(-2i64) == 2i64); - assert(absi(2i8) == 2i64); - assert(absi(-2i8) == 2i64); - assert(absi(2i16) == 2i64); - assert(absi(-2i16) == 2i64); - assert(absi(2i32) == 2i64); - assert(absi(-2i32) == 2i64); - assert(absi(2i64) == 2i64); - assert(absi(-2i64) == 2i64); + // Workaround casting issue where (-types::I8_MIN: u8) has a value not + // equal to (-types::I8_MIN: u16) + let m8 = (-types::I8_MIN: u8); + let m16 = (-types::I16_MIN: u16); + let m32 = (-types::I32_MIN: u32); + let m64 = (-types::I64_MIN: u64); + + assert(absi8(2i8) == 2u8); + assert(absi8(-2i8) == 2u8); + assert(absi8(types::I8_MIN) == m8); + assert(absi16(2i16) == 2u16); + assert(absi16(-2i16) == 2u16); + assert(absi16(types::I16_MIN) == m16); + assert(absi32(2i32) == 2u32); + assert(absi32(-2i32) == 2u32); + assert(absi32(types::I32_MIN) == m32); + assert(absi64(2i64) == 2u64); + assert(absi64(-2i64) == 2u64); + assert(absi64(types::I64_MIN) == m64); + assert(absi(2i8) == 2u64); + assert(absi(-2i8) == 2u64); + assert(absi(types::I8_MIN) == (m8: u64)); + assert(absi(2i16) == 2u64); + assert(absi(-2i16) == 2u64); + assert(absi(types::I16_MIN) == (m16: u64)); + assert(absi(2i32) == 2u64); + assert(absi(-2i32) == 2u64); + assert(absi(types::I32_MIN) == (m32: u64)); + assert(absi(2i64) == 2u64); + assert(absi(-2i64) == 2u64); + assert(absi(types::I64_MIN) == (m64: u64)); }; // Return 1 if n is positive, -1 if it's negative and 0 if it's 0. @@ -119,15 +134,15 @@ export fn signi64(n: i64) i64 = { export fn signi(n: types::integer) i64 = { match (n) { case let n: i8 => - return (signi8(n): i64); + return signi8(n): i64; case let n: i16 => - return (signi16(n): i64); + return signi16(n): i64; case let n: i32 => - return (signi32(n): i64); + return signi32(n): i64; case let n: i64 => - return (signi64(n): i64); + return signi64(n): i64; case let n: int => - return (signi64(n): i64); + return signi64(n): i64; }; };