mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
stage1: fix comptime saturation subtraction
- also simplifies code - adding a few more tests closes #10870
This commit is contained in:
parent
be98f30a2d
commit
c6cd919a18
@ -476,9 +476,15 @@ void bigint_min(BigInt* dest, const BigInt *op1, const BigInt *op2) {
|
|||||||
/// signed bounds are [-2^(bit_count-1)..2^(bit_count-1)-1]
|
/// signed bounds are [-2^(bit_count-1)..2^(bit_count-1)-1]
|
||||||
/// unsigned bounds are [0..2^bit_count-1]
|
/// unsigned bounds are [0..2^bit_count-1]
|
||||||
void bigint_clamp_by_bitcount(BigInt* dest, uint32_t bit_count, bool is_signed) {
|
void bigint_clamp_by_bitcount(BigInt* dest, uint32_t bit_count, bool is_signed) {
|
||||||
|
bool is_negative = dest->is_negative;
|
||||||
|
// unsigned and dest->is_negative => clamp to 0
|
||||||
|
if (is_negative && !is_signed) {
|
||||||
|
bigint_deinit(dest);
|
||||||
|
bigint_init_unsigned(dest, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// compute the number of bits required to store the value, and use that
|
// compute the number of bits required to store the value, and use that
|
||||||
// to decide whether to clamp the result
|
// to decide whether to clamp the result
|
||||||
bool is_negative = dest->is_negative;
|
|
||||||
// to workaround the fact this bits_needed calculation would yield 65 or more for
|
// to workaround the fact this bits_needed calculation would yield 65 or more for
|
||||||
// all negative numbers, set is_negative to false. this is a cheap way to find
|
// all negative numbers, set is_negative to false. this is a cheap way to find
|
||||||
// bits_needed(abs(dest)).
|
// bits_needed(abs(dest)).
|
||||||
@ -511,11 +517,6 @@ void bigint_clamp_by_bitcount(BigInt* dest, uint32_t bit_count, bool is_signed)
|
|||||||
bigint_deinit(dest);
|
bigint_deinit(dest);
|
||||||
*dest = bound_sub_one;
|
*dest = bound_sub_one;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if(is_negative) {
|
|
||||||
bigint_deinit(dest);
|
|
||||||
bigint_init_unsigned(dest, 0);
|
|
||||||
return; // skips setting is_negative which would be invalid
|
|
||||||
} else {
|
} else {
|
||||||
BigInt bound;
|
BigInt bound;
|
||||||
bigint_shl(&bound, &one, &bit_count_big);
|
bigint_shl(&bound, &one, &bit_count_big);
|
||||||
@ -526,7 +527,6 @@ void bigint_clamp_by_bitcount(BigInt* dest, uint32_t bit_count, bool is_signed)
|
|||||||
*dest = bound_sub_one;
|
*dest = bound_sub_one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
dest->is_negative = is_negative;
|
dest->is_negative = is_negative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,12 +8,17 @@ test "saturating add" {
|
|||||||
const S = struct {
|
const S = struct {
|
||||||
fn doTheTest() !void {
|
fn doTheTest() !void {
|
||||||
try testSatAdd(i8, -3, 10, 7);
|
try testSatAdd(i8, -3, 10, 7);
|
||||||
|
try testSatAdd(i8, 3, -10, -7);
|
||||||
try testSatAdd(i8, -128, -128, -128);
|
try testSatAdd(i8, -128, -128, -128);
|
||||||
try testSatAdd(i2, 1, 1, 1);
|
try testSatAdd(i2, 1, 1, 1);
|
||||||
|
try testSatAdd(i2, 1, -1, 0);
|
||||||
|
try testSatAdd(i2, -1, -1, -2);
|
||||||
try testSatAdd(i64, maxInt(i64), 1, maxInt(i64));
|
try testSatAdd(i64, maxInt(i64), 1, maxInt(i64));
|
||||||
try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0);
|
try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0);
|
||||||
try testSatAdd(i128, minInt(i128), maxInt(i128), -1);
|
try testSatAdd(i128, minInt(i128), maxInt(i128), -1);
|
||||||
try testSatAdd(i8, 127, 127, 127);
|
try testSatAdd(i8, 127, 127, 127);
|
||||||
|
try testSatAdd(u2, 0, 0, 0);
|
||||||
|
try testSatAdd(u2, 0, 1, 1);
|
||||||
try testSatAdd(u8, 3, 10, 13);
|
try testSatAdd(u8, 3, 10, 13);
|
||||||
try testSatAdd(u8, 255, 255, 255);
|
try testSatAdd(u8, 255, 255, 255);
|
||||||
try testSatAdd(u2, 3, 2, 3);
|
try testSatAdd(u2, 3, 2, 3);
|
||||||
@ -34,7 +39,11 @@ test "saturating add" {
|
|||||||
comptime try S.doTheTest();
|
comptime try S.doTheTest();
|
||||||
|
|
||||||
comptime try S.testSatAdd(comptime_int, 0, 0, 0);
|
comptime try S.testSatAdd(comptime_int, 0, 0, 0);
|
||||||
|
comptime try S.testSatAdd(comptime_int, -1, 1, 0);
|
||||||
comptime try S.testSatAdd(comptime_int, 3, 2, 5);
|
comptime try S.testSatAdd(comptime_int, 3, 2, 5);
|
||||||
|
comptime try S.testSatAdd(comptime_int, -3, -2, -5);
|
||||||
|
comptime try S.testSatAdd(comptime_int, 3, -2, 1);
|
||||||
|
comptime try S.testSatAdd(comptime_int, -3, 2, -1);
|
||||||
comptime try S.testSatAdd(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 1119305249183743626545271163355074748512);
|
comptime try S.testSatAdd(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 1119305249183743626545271163355074748512);
|
||||||
comptime try S.testSatAdd(comptime_int, 7, -593423721213448152027139550640105366508, -593423721213448152027139550640105366501);
|
comptime try S.testSatAdd(comptime_int, 7, -593423721213448152027139550640105366508, -593423721213448152027139550640105366501);
|
||||||
}
|
}
|
||||||
@ -43,14 +52,20 @@ test "saturating subtraction" {
|
|||||||
const S = struct {
|
const S = struct {
|
||||||
fn doTheTest() !void {
|
fn doTheTest() !void {
|
||||||
try testSatSub(i8, -3, 10, -13);
|
try testSatSub(i8, -3, 10, -13);
|
||||||
|
try testSatSub(i8, -3, -10, 7);
|
||||||
try testSatSub(i8, -128, -128, 0);
|
try testSatSub(i8, -128, -128, 0);
|
||||||
try testSatSub(i8, -1, 127, -128);
|
try testSatSub(i8, -1, 127, -128);
|
||||||
|
try testSatSub(i2, 1, 1, 0);
|
||||||
|
try testSatSub(i2, 1, -1, 1);
|
||||||
|
try testSatSub(i2, -2, -2, 0);
|
||||||
try testSatSub(i64, minInt(i64), 1, minInt(i64));
|
try testSatSub(i64, minInt(i64), 1, minInt(i64));
|
||||||
try testSatSub(i128, maxInt(i128), -1, maxInt(i128));
|
try testSatSub(i128, maxInt(i128), -1, maxInt(i128));
|
||||||
try testSatSub(i128, minInt(i128), -maxInt(i128), -1);
|
try testSatSub(i128, minInt(i128), -maxInt(i128), -1);
|
||||||
|
try testSatSub(u2, 0, 0, 0);
|
||||||
|
try testSatSub(u2, 0, 1, 0);
|
||||||
|
try testSatSub(u5, 0, 31, 0);
|
||||||
try testSatSub(u8, 10, 3, 7);
|
try testSatSub(u8, 10, 3, 7);
|
||||||
try testSatSub(u8, 0, 255, 0);
|
try testSatSub(u8, 0, 255, 0);
|
||||||
try testSatSub(u5, 0, 31, 0);
|
|
||||||
try testSatSub(u128, 0, maxInt(u128), 0);
|
try testSatSub(u128, 0, maxInt(u128), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +82,11 @@ test "saturating subtraction" {
|
|||||||
comptime try S.doTheTest();
|
comptime try S.doTheTest();
|
||||||
|
|
||||||
comptime try S.testSatSub(comptime_int, 0, 0, 0);
|
comptime try S.testSatSub(comptime_int, 0, 0, 0);
|
||||||
|
comptime try S.testSatSub(comptime_int, 1, 1, 0);
|
||||||
comptime try S.testSatSub(comptime_int, 3, 2, 1);
|
comptime try S.testSatSub(comptime_int, 3, 2, 1);
|
||||||
|
comptime try S.testSatSub(comptime_int, -3, -2, -1);
|
||||||
|
comptime try S.testSatSub(comptime_int, 3, -2, 5);
|
||||||
|
comptime try S.testSatSub(comptime_int, -3, 2, -5);
|
||||||
comptime try S.testSatSub(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 182846383813587550256162760261375991602);
|
comptime try S.testSatSub(comptime_int, 651075816498665588400716961808225370057, 468229432685078038144554201546849378455, 182846383813587550256162760261375991602);
|
||||||
comptime try S.testSatSub(comptime_int, 7, -593423721213448152027139550640105366508, 593423721213448152027139550640105366515);
|
comptime try S.testSatSub(comptime_int, 7, -593423721213448152027139550640105366508, 593423721213448152027139550640105366515);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user