Compile error for signed integer math

Output compile errors when signed integer types are used on functions
where the answer might've been a complex number but that functionality hasn't
been implemented.

This applies to sqrt, log, log2, log10 and ln.

A test which used a signed integer was also changed to use an unsigned
integer instead.
This commit is contained in:
antlilja 2021-04-02 14:52:47 +02:00
parent cc435dab2f
commit d4dc2eb807
No known key found for this signature in database
GPG Key ID: 882463E39664B8B0
5 changed files with 19 additions and 11 deletions

View File

@ -36,8 +36,9 @@ pub fn ln(x: anytype) @TypeOf(x) {
.ComptimeInt => { .ComptimeInt => {
return @as(comptime_int, math.floor(ln_64(@as(f64, x)))); return @as(comptime_int, math.floor(ln_64(@as(f64, x))));
}, },
.Int => { .Int => |IntType| switch (IntType.signedness) {
return @as(T, math.floor(ln_64(@as(f64, x)))); .signed => return @compileError("ln not implemented for signed integers"),
.unsigned => return @as(T, math.floor(ln_64(@as(f64, x)))),
}, },
else => @compileError("ln not implemented for " ++ @typeName(T)), else => @compileError("ln not implemented for " ++ @typeName(T)),
} }

View File

@ -31,9 +31,11 @@ pub fn log(comptime T: type, base: T, x: T) T {
.ComptimeInt => { .ComptimeInt => {
return @as(comptime_int, math.floor(math.ln(@as(f64, x)) / math.ln(float_base))); return @as(comptime_int, math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));
}, },
.Int => {
// TODO implement integer log without using float math // TODO implement integer log without using float math
return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base))); .Int => |IntType| switch (IntType.signedness) {
.signed => return @compileError("log not implemented for signed integers"),
.unsigned => return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base))),
}, },
.Float => { .Float => {
@ -53,7 +55,7 @@ pub fn log(comptime T: type, base: T, x: T) T {
test "math.log integer" { test "math.log integer" {
expect(log(u8, 2, 0x1) == 0); expect(log(u8, 2, 0x1) == 0);
expect(log(u8, 2, 0x2) == 1); expect(log(u8, 2, 0x2) == 1);
expect(log(i16, 2, 0x72) == 6); expect(log(u16, 2, 0x72) == 6);
expect(log(u32, 2, 0xFFFFFF) == 23); expect(log(u32, 2, 0xFFFFFF) == 23);
expect(log(u64, 2, 0x7FF0123456789ABC) == 62); expect(log(u64, 2, 0x7FF0123456789ABC) == 62);
} }

View File

@ -37,8 +37,9 @@ pub fn log10(x: anytype) @TypeOf(x) {
.ComptimeInt => { .ComptimeInt => {
return @as(comptime_int, math.floor(log10_64(@as(f64, x)))); return @as(comptime_int, math.floor(log10_64(@as(f64, x))));
}, },
.Int => { .Int => |IntType| switch (IntType.signedness) {
return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x)))); .signed => return @compileError("log10 not implemented for signed integers"),
.unsigned => return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x)))),
}, },
else => @compileError("log10 not implemented for " ++ @typeName(T)), else => @compileError("log10 not implemented for " ++ @typeName(T)),
} }

View File

@ -43,8 +43,9 @@ pub fn log2(x: anytype) @TypeOf(x) {
}) : (result += 1) {} }) : (result += 1) {}
return result; return result;
}, },
.Int => { .Int => |IntType| switch (IntType.signedness) {
return math.log2_int(T, x); .signed => return @compileError("log2 not implemented for signed integers"),
.unsigned => return math.log2_int(T, x),
}, },
else => @compileError("log2 not implemented for " ++ @typeName(T)), else => @compileError("log2 not implemented for " ++ @typeName(T)),
} }

View File

@ -31,7 +31,10 @@ pub fn sqrt(x: anytype) Sqrt(@TypeOf(x)) {
} }
return @as(T, sqrt_int(u128, x)); return @as(T, sqrt_int(u128, x));
}, },
.Int => return sqrt_int(T, x), .Int => |IntType| switch (IntType.signedness) {
.signed => return @compileError("sqrt not implemented for signed integers"),
.unsigned => return sqrt_int(T, x),
},
else => @compileError("sqrt not implemented for " ++ @typeName(T)), else => @compileError("sqrt not implemented for " ++ @typeName(T)),
} }
} }