2017-01-05 00:57:48 -08:00
|
|
|
const assert = @import("std").debug.assert;
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "division" {
|
|
|
|
testDivision();
|
|
|
|
comptime testDivision();
|
|
|
|
}
|
|
|
|
fn testDivision() {
|
|
|
|
assert(div(u32, 13, 3) == 4);
|
|
|
|
assert(div(f32, 1.0, 2.0) == 0.5);
|
|
|
|
|
|
|
|
assert(divExact(u32, 55, 11) == 5);
|
|
|
|
assert(divExact(i32, -55, 11) == -5);
|
|
|
|
assert(divExact(f32, 55.0, 11.0) == 5.0);
|
|
|
|
assert(divExact(f32, -55.0, 11.0) == -5.0);
|
|
|
|
|
|
|
|
assert(divFloor(i32, 5, 3) == 1);
|
|
|
|
assert(divFloor(i32, -5, 3) == -2);
|
|
|
|
assert(divFloor(f32, 5.0, 3.0) == 1.0);
|
|
|
|
assert(divFloor(f32, -5.0, 3.0) == -2.0);
|
|
|
|
assert(divFloor(i32, -0x80000000, -2) == 0x40000000);
|
|
|
|
assert(divFloor(i32, 0, -0x80000000) == 0);
|
|
|
|
assert(divFloor(i32, -0x40000001, 0x40000000) == -2);
|
|
|
|
assert(divFloor(i32, -0x80000000, 1) == -0x80000000);
|
|
|
|
|
|
|
|
assert(divTrunc(i32, 5, 3) == 1);
|
|
|
|
assert(divTrunc(i32, -5, 3) == -1);
|
|
|
|
assert(divTrunc(f32, 5.0, 3.0) == 1.0);
|
|
|
|
assert(divTrunc(f32, -5.0, 3.0) == -1.0);
|
|
|
|
}
|
|
|
|
fn div(comptime T: type, a: T, b: T) -> T {
|
|
|
|
a / b
|
2016-12-18 21:41:37 -08:00
|
|
|
}
|
2017-05-06 20:13:12 -07:00
|
|
|
fn divExact(comptime T: type, a: T, b: T) -> T {
|
2016-12-18 21:41:37 -08:00
|
|
|
@divExact(a, b)
|
|
|
|
}
|
2017-05-06 20:13:12 -07:00
|
|
|
fn divFloor(comptime T: type, a: T, b: T) -> T {
|
|
|
|
@divFloor(a, b)
|
2016-12-18 21:41:37 -08:00
|
|
|
}
|
2017-05-06 20:13:12 -07:00
|
|
|
fn divTrunc(comptime T: type, a: T, b: T) -> T {
|
|
|
|
@divTrunc(a, b)
|
2016-12-18 21:41:37 -08:00
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "@addWithOverflow" {
|
2016-12-18 21:41:37 -08:00
|
|
|
var result: u8 = undefined;
|
|
|
|
assert(@addWithOverflow(u8, 250, 100, &result));
|
|
|
|
assert(!@addWithOverflow(u8, 100, 150, &result));
|
|
|
|
assert(result == 250);
|
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
// TODO test mulWithOverflow
|
|
|
|
// TODO test subWithOverflow
|
|
|
|
|
|
|
|
test "@shlWithOverflow" {
|
2016-12-18 21:41:37 -08:00
|
|
|
var result: u16 = undefined;
|
|
|
|
assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
|
|
|
|
assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
|
|
|
|
assert(result == 0b1011111111111100);
|
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "@clz" {
|
2017-06-26 11:41:47 -07:00
|
|
|
testClz();
|
|
|
|
comptime testClz();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testClz() {
|
|
|
|
assert(clz(u8(0b00001010)) == 4);
|
|
|
|
assert(clz(u8(0b10001010)) == 0);
|
|
|
|
assert(clz(u8(0b00000000)) == 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn clz(x: var) -> usize {
|
|
|
|
@clz(x)
|
2016-12-18 21:41:37 -08:00
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "@ctz" {
|
2017-06-26 11:41:47 -07:00
|
|
|
testCtz();
|
|
|
|
comptime testCtz();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testCtz() {
|
|
|
|
assert(ctz(u8(0b10100000)) == 5);
|
|
|
|
assert(ctz(u8(0b10001010)) == 1);
|
|
|
|
assert(ctz(u8(0b00000000)) == 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ctz(x: var) -> usize {
|
|
|
|
@ctz(x)
|
2016-12-18 21:41:37 -08:00
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "assignment operators" {
|
|
|
|
var i: u32 = 0;
|
2016-12-21 21:55:21 -08:00
|
|
|
i += 5; assert(i == 5);
|
|
|
|
i -= 2; assert(i == 3);
|
|
|
|
i *= 20; assert(i == 60);
|
|
|
|
i /= 3; assert(i == 20);
|
|
|
|
i %= 11; assert(i == 9);
|
|
|
|
i <<= 1; assert(i == 18);
|
|
|
|
i >>= 2; assert(i == 4);
|
|
|
|
i = 6;
|
|
|
|
i &= 5; assert(i == 4);
|
|
|
|
i ^= 6; assert(i == 2);
|
|
|
|
i = 6;
|
|
|
|
i |= 3; assert(i == 7);
|
|
|
|
}
|
|
|
|
|
2017-05-23 18:38:31 -07:00
|
|
|
test "three expr in a row" {
|
2017-05-06 20:13:12 -07:00
|
|
|
testThreeExprInARow(false, true);
|
|
|
|
comptime testThreeExprInARow(false, true);
|
2017-01-08 19:25:38 -08:00
|
|
|
}
|
|
|
|
fn testThreeExprInARow(f: bool, t: bool) {
|
2017-03-26 02:21:28 -07:00
|
|
|
assertFalse(f or f or f);
|
|
|
|
assertFalse(t and t and f);
|
2016-12-21 22:20:08 -08:00
|
|
|
assertFalse(1 | 2 | 4 != 7);
|
|
|
|
assertFalse(3 ^ 6 ^ 8 != 13);
|
|
|
|
assertFalse(7 & 14 & 28 != 4);
|
|
|
|
assertFalse(9 << 1 << 2 != 9 << 3);
|
|
|
|
assertFalse(90 >> 1 >> 2 != 90 >> 3);
|
|
|
|
assertFalse(100 - 1 + 1000 != 1099);
|
|
|
|
assertFalse(5 * 4 / 2 % 3 != 1);
|
|
|
|
assertFalse(i32(i32(5)) != 5);
|
|
|
|
assertFalse(!!false);
|
|
|
|
assertFalse(i32(7) != --(i32(7)));
|
|
|
|
}
|
|
|
|
fn assertFalse(b: bool) {
|
|
|
|
assert(!b);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "const number literal" {
|
2016-12-21 22:20:08 -08:00
|
|
|
const one = 1;
|
|
|
|
const eleven = ten + one;
|
|
|
|
|
|
|
|
assert(eleven == 11);
|
|
|
|
}
|
|
|
|
const ten = 10;
|
|
|
|
|
|
|
|
|
2016-12-21 21:55:21 -08:00
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "unsigned wrapping" {
|
2016-12-26 00:44:59 -08:00
|
|
|
testUnsignedWrappingEval(@maxValue(u32));
|
2017-05-06 20:13:12 -07:00
|
|
|
comptime testUnsignedWrappingEval(@maxValue(u32));
|
2016-12-26 00:44:59 -08:00
|
|
|
}
|
|
|
|
fn testUnsignedWrappingEval(x: u32) {
|
|
|
|
const zero = x +% 1;
|
|
|
|
assert(zero == 0);
|
|
|
|
const orig = zero -% 1;
|
|
|
|
assert(orig == @maxValue(u32));
|
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "signed wrapping" {
|
2016-12-26 00:44:59 -08:00
|
|
|
testSignedWrappingEval(@maxValue(i32));
|
2017-05-06 20:13:12 -07:00
|
|
|
comptime testSignedWrappingEval(@maxValue(i32));
|
2016-12-26 00:44:59 -08:00
|
|
|
}
|
|
|
|
fn testSignedWrappingEval(x: i32) {
|
|
|
|
const min_val = x +% 1;
|
|
|
|
assert(min_val == @minValue(i32));
|
|
|
|
const max_val = min_val -% 1;
|
|
|
|
assert(max_val == @maxValue(i32));
|
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "negation wrapping" {
|
2016-12-26 00:44:59 -08:00
|
|
|
testNegationWrappingEval(@minValue(i16));
|
2017-05-06 20:13:12 -07:00
|
|
|
comptime testNegationWrappingEval(@minValue(i16));
|
2016-12-26 00:44:59 -08:00
|
|
|
}
|
|
|
|
fn testNegationWrappingEval(x: i16) {
|
|
|
|
assert(x == -32768);
|
|
|
|
const neg = -%x;
|
|
|
|
assert(neg == -32768);
|
|
|
|
}
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "unsigned 64-bit division" {
|
|
|
|
test_u64_div();
|
|
|
|
comptime test_u64_div();
|
|
|
|
}
|
|
|
|
fn test_u64_div() {
|
|
|
|
const result = divWithResult(1152921504606846976, 34359738365);
|
2016-12-26 00:44:59 -08:00
|
|
|
assert(result.quotient == 33554432);
|
|
|
|
assert(result.remainder == 100663296);
|
|
|
|
}
|
2017-05-06 20:13:12 -07:00
|
|
|
fn divWithResult(a: u64, b: u64) -> DivResult {
|
2016-12-26 00:44:59 -08:00
|
|
|
DivResult {
|
|
|
|
.quotient = a / b,
|
|
|
|
.remainder = a % b,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const DivResult = struct {
|
|
|
|
quotient: u64,
|
|
|
|
remainder: u64,
|
|
|
|
};
|
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "binary not" {
|
2017-01-22 20:20:53 -08:00
|
|
|
assert(comptime {~u16(0b1010101010101010) == 0b0101010101010101});
|
|
|
|
assert(comptime {~u64(2147483647) == 18446744071562067968});
|
2016-12-30 23:23:39 -08:00
|
|
|
testBinaryNot(0b1010101010101010);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testBinaryNot(x: u16) {
|
|
|
|
assert(~x == 0b0101010101010101);
|
|
|
|
}
|
2017-02-16 14:08:55 -08:00
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "small int addition" {
|
2017-04-17 21:05:09 -07:00
|
|
|
var x: @IntType(false, 2) = 0;
|
2017-02-16 14:08:55 -08:00
|
|
|
assert(x == 0);
|
|
|
|
|
|
|
|
x += 1;
|
|
|
|
assert(x == 1);
|
|
|
|
|
|
|
|
x += 1;
|
|
|
|
assert(x == 2);
|
|
|
|
|
|
|
|
x += 1;
|
|
|
|
assert(x == 3);
|
|
|
|
|
|
|
|
var result: @typeOf(x) = 3;
|
|
|
|
assert(@addWithOverflow(@typeOf(x), x, 1, &result));
|
|
|
|
|
|
|
|
assert(result == 0);
|
|
|
|
}
|
2017-02-26 13:30:15 -08:00
|
|
|
|
2017-05-06 20:13:12 -07:00
|
|
|
test "float equality" {
|
2017-02-26 13:30:15 -08:00
|
|
|
const x: f64 = 0.012;
|
|
|
|
const y: f64 = x + 1.0;
|
|
|
|
|
|
|
|
testFloatEqualityImpl(x, y);
|
|
|
|
comptime testFloatEqualityImpl(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn testFloatEqualityImpl(x: f64, y: f64) {
|
|
|
|
const y2 = x + 1.0;
|
|
|
|
assert(y == y2);
|
|
|
|
}
|
2017-05-06 20:59:57 -07:00
|
|
|
|
|
|
|
test "allow signed integer division/remainder when values are comptime known and positive or exact" {
|
|
|
|
assert(5 / 3 == 1);
|
|
|
|
assert(-5 / -3 == 1);
|
|
|
|
assert(-6 / 3 == -2);
|
|
|
|
|
|
|
|
assert(5 % 3 == 2);
|
|
|
|
assert(-6 % 3 == 0);
|
|
|
|
}
|
2017-06-26 11:41:47 -07:00
|
|
|
|
|
|
|
test "float literal parsing" {
|
|
|
|
comptime assert(0x1.0 == 1.0);
|
|
|
|
}
|
2017-08-06 23:06:06 -07:00
|
|
|
|
|
|
|
test "hex float literal within range" {
|
|
|
|
const a = 0x1.0p1023;
|
|
|
|
const b = 0x0.1p1027;
|
|
|
|
const c = 0x1.0p-1022;
|
|
|
|
}
|
2017-08-09 07:09:38 -07:00
|
|
|
|
|
|
|
test "truncating shift left" {
|
|
|
|
testShlTrunc(@maxValue(u16));
|
|
|
|
comptime testShlTrunc(@maxValue(u16));
|
|
|
|
}
|
|
|
|
fn testShlTrunc(x: u16) {
|
|
|
|
const shifted = x << 1;
|
|
|
|
assert(shifted == 65534);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "truncating shift right" {
|
|
|
|
testShrTrunc(@maxValue(u16));
|
|
|
|
comptime testShrTrunc(@maxValue(u16));
|
|
|
|
}
|
|
|
|
fn testShrTrunc(x: u16) {
|
|
|
|
const shifted = x >> 1;
|
|
|
|
assert(shifted == 32767);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "exact shift left" {
|
|
|
|
testShlExact(0b00110101);
|
|
|
|
comptime testShlExact(0b00110101);
|
|
|
|
}
|
|
|
|
fn testShlExact(x: u8) {
|
|
|
|
const shifted = @shlExact(x, 2);
|
|
|
|
assert(shifted == 0b11010100);
|
|
|
|
}
|
|
|
|
|
|
|
|
test "exact shift right" {
|
|
|
|
testShrExact(0b10110100);
|
|
|
|
comptime testShrExact(0b10110100);
|
|
|
|
}
|
|
|
|
fn testShrExact(x: u8) {
|
|
|
|
const shifted = @shrExact(x, 2);
|
|
|
|
assert(shifted == 0b00101101);
|
|
|
|
}
|
2017-08-16 16:07:35 -07:00
|
|
|
|
|
|
|
test "big number addition" {
|
|
|
|
comptime {
|
|
|
|
assert(
|
|
|
|
35361831660712422535336160538497375248 +
|
|
|
|
101752735581729509668353361206450473702 ==
|
|
|
|
137114567242441932203689521744947848950);
|
|
|
|
assert(
|
|
|
|
594491908217841670578297176641415611445982232488944558774612 +
|
|
|
|
390603545391089362063884922208143568023166603618446395589768 ==
|
|
|
|
985095453608931032642182098849559179469148836107390954364380);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
test "big number multiplication" {
|
|
|
|
comptime {
|
|
|
|
assert(
|
|
|
|
45960427431263824329884196484953148229 *
|
|
|
|
128339149605334697009938835852565949723 ==
|
|
|
|
5898522172026096622534201617172456926982464453350084962781392314016180490567);
|
|
|
|
assert(
|
|
|
|
594491908217841670578297176641415611445982232488944558774612 *
|
|
|
|
390603545391089362063884922208143568023166603618446395589768 ==
|
|
|
|
232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
|
|
|
|
}
|
|
|
|
}
|