hare

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

ints.ha (3749B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use types;
      5 
      6 // Returns the absolute value of signed integer n.
      7 export fn absi8(n: i8) u8 = {
      8 	if (n < 0i8) {
      9 		return -n: u8;
     10 	} else {
     11 		return n: u8;
     12 	};
     13 };
     14 
     15 // Returns the absolute value of signed integer n.
     16 export fn absi16(n: i16) u16 = {
     17 	if (n < 0i16) {
     18 		return -n: u16;
     19 	} else {
     20 		return n: u16;
     21 	};
     22 };
     23 
     24 // Returns the absolute value of signed integer n.
     25 export fn absi32(n: i32) u32 = {
     26 	if (n < 0i32) {
     27 		return -n: u32;
     28 	} else {
     29 		return n: u32;
     30 	};
     31 };
     32 
     33 // Returns the absolute value of signed integer n.
     34 export fn absi64(n: i64) u64 = {
     35 	if (n < 0i64) {
     36 		return -n: u64;
     37 	} else {
     38 		return n: u64;
     39 	};
     40 };
     41 
     42 // Returns the absolute value of signed integer n.
     43 export fn absi(n: types::signed) u64 = {
     44 	match (n) {
     45 	case let n: i8 =>
     46 		return absi8(n): u64;
     47 	case let n: i16 =>
     48 		return absi16(n): u64;
     49 	case let n: i32 =>
     50 		return absi32(n): u64;
     51 	case let n: i64 =>
     52 		return absi64(n): u64;
     53 	case let n: int =>
     54 		return absi64(n): u64;
     55 	};
     56 };
     57 
     58 @test fn absi() void = {
     59 	// Workaround casting issue where (-types::I8_MIN: u8) has a value not
     60 	// equal to (-types::I8_MIN: u16)
     61 	let m8 = (-types::I8_MIN: u8);
     62 	let m16 = (-types::I16_MIN: u16);
     63 	let m32 = (-types::I32_MIN: u32);
     64 	let m64 = (-types::I64_MIN: u64);
     65 
     66 	assert(absi8(2i8) == 2u8);
     67 	assert(absi8(-2i8) == 2u8);
     68 	assert(absi8(types::I8_MIN) == m8);
     69 	assert(absi16(2i16) == 2u16);
     70 	assert(absi16(-2i16) == 2u16);
     71 	assert(absi16(types::I16_MIN) == m16);
     72 	assert(absi32(2i32) == 2u32);
     73 	assert(absi32(-2i32) == 2u32);
     74 	assert(absi32(types::I32_MIN) == m32);
     75 	assert(absi64(2i64) == 2u64);
     76 	assert(absi64(-2i64) == 2u64);
     77 	assert(absi64(types::I64_MIN) == m64);
     78 	assert(absi(2i8) == 2u64);
     79 	assert(absi(-2i8) == 2u64);
     80 	assert(absi(types::I8_MIN) == (m8: u64));
     81 	assert(absi(2i16) == 2u64);
     82 	assert(absi(-2i16) == 2u64);
     83 	assert(absi(types::I16_MIN) == (m16: u64));
     84 	assert(absi(2i32) == 2u64);
     85 	assert(absi(-2i32) == 2u64);
     86 	assert(absi(types::I32_MIN) == (m32: u64));
     87 	assert(absi(2i64) == 2u64);
     88 	assert(absi(-2i64) == 2u64);
     89 	assert(absi(types::I64_MIN) == (m64: u64));
     90 };
     91 
     92 // Return 1 if n is positive, -1 if it's negative and 0 if it's 0.
     93 export fn signi8(n: i8) i8 = {
     94 	if (n > 0i8) {
     95 		return 1i8;
     96 	};
     97 	if (n < 0i8) {
     98 		return -1i8;
     99 	};
    100 	return 0i8;
    101 };
    102 
    103 // Return 1 if n is positive, -1 if it's negative and 0 if it's 0.
    104 export fn signi16(n: i16) i16 = {
    105 	if (n > 0i16) {
    106 		return 1i16;
    107 	};
    108 	if (n < 0i16) {
    109 		return -1i16;
    110 	};
    111 	return 0i16;
    112 };
    113 
    114 // Return 1 if n is positive, -1 if it's negative and 0 if it's 0.
    115 export fn signi32(n: i32) i32 = {
    116 	if (n > 0i32) {
    117 		return 1i32;
    118 	};
    119 	if (n < 0i32) {
    120 		return -1i32;
    121 	};
    122 	return 0i32;
    123 };
    124 
    125 // Return 1 if n is positive, -1 if it's negative and 0 if it's 0.
    126 export fn signi64(n: i64) i64 = {
    127 	if (n > 0i64) {
    128 		return 1i64;
    129 	};
    130 	if (n < 0i64) {
    131 		return -1i64;
    132 	};
    133 	return 0i64;
    134 };
    135 
    136 // Return 1 if n is positive, -1 if it's negative and 0 if it's 0.
    137 export fn signi(n: types::signed) i64 = {
    138 	match (n) {
    139 	case let n: i8 =>
    140 		return signi8(n): i64;
    141 	case let n: i16 =>
    142 		return signi16(n): i64;
    143 	case let n: i32 =>
    144 		return signi32(n): i64;
    145 	case let n: i64 =>
    146 		return signi64(n): i64;
    147 	case let n: int =>
    148 		return signi64(n): i64;
    149 	};
    150 };
    151 
    152 @test fn signi() void = {
    153 	assert(signi8(2i8) == 1i8);
    154 	assert(signi8(-2i8) == -1i8);
    155 	assert(signi8(0i8) == 0i8);
    156 	assert(signi16(2i16) == 1i16);
    157 	assert(signi16(-2i16) == -1i16);
    158 	assert(signi16(0i16) == 0i16);
    159 	assert(signi32(2i32) == 1i32);
    160 	assert(signi32(-2i32) == -1i32);
    161 	assert(signi32(0i32) == 0i32);
    162 	assert(signi64(2i64) == 1i64);
    163 	assert(signi64(-2i64) == -1i64);
    164 	assert(signi64(0i64) == 0i64);
    165 	assert(signi(2i16) == 1i64);
    166 	assert(signi(-2i16) == -1i64);
    167 	assert(signi(0i16) == 0i64);
    168 };