362 lines
18 KiB
C++
Executable File
362 lines
18 KiB
C++
Executable File
#include "test_ckdint.hpp"
|
|
|
|
extern "C"
|
|
{
|
|
#include "guf_math_ckdint.h"
|
|
}
|
|
|
|
/*
|
|
CkdIntTest:
|
|
*/
|
|
|
|
void CkdIntTest::run()
|
|
{
|
|
push_check_name("test_ckd");
|
|
test_ckd();
|
|
pop_check_name();
|
|
|
|
push_check_name("test_ckd_uint");
|
|
test_ckd_uint();
|
|
pop_check_name();
|
|
}
|
|
|
|
void CkdIntTest::test_ckd()
|
|
{
|
|
for (int32_t a = INT8_MIN; a <= INT8_MAX; ++a) {
|
|
for (int32_t b = INT8_MIN; b <= INT8_MAX; ++b) {
|
|
const int32_t add_res = a + b;
|
|
const guf_math_ckd_result ckd_add = guf_ckd_add_i8((int8_t)a, (int8_t)b);
|
|
TEST_CHECK(ckd_add == guf_ckd_add_i8((int8_t)b, (int8_t)a));
|
|
TEST_CHECK(ckd_add == guf_ckd_add_least_i8((int_least8_t)a, (int_least8_t)b));
|
|
if (add_res > INT8_MAX) {
|
|
TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_POS);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == INT8_MAX);
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == INT8_MIN + (add_res % (INT8_MAX + 1)));
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
}
|
|
else if (add_res < INT8_MIN) {
|
|
TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == INT8_MIN);
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == INT8_MAX - (-add_res % (-INT8_MIN + 1)));
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
}
|
|
else {
|
|
TEST_CHECK(ckd_add == GUF_MATH_CKD_SUCCESS);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == add_res);
|
|
TEST_CHECK(guf_saturating_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == add_res);
|
|
TEST_CHECK(guf_wrapping_add_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
}
|
|
|
|
const int32_t sub_res = a - b;
|
|
const guf_math_ckd_result ckd_sub = guf_ckd_sub_i8((int8_t)a, (int8_t)b);
|
|
TEST_CHECK(ckd_sub == guf_ckd_sub_least_i8((int_least8_t)a, (int_least8_t)b));
|
|
if (sub_res > INT8_MAX) {
|
|
TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_POS);
|
|
int8_t saturated;
|
|
TEST_CHECK(guf_saturating_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == INT8_MAX);
|
|
int8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == INT8_MIN + (sub_res % (INT8_MAX + 1)));
|
|
} else if (sub_res < INT8_MIN) {
|
|
TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
int8_t saturated;
|
|
TEST_CHECK(guf_saturating_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == INT8_MIN);
|
|
int8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == INT8_MAX - (-sub_res % (-INT8_MIN + 1)));
|
|
} else {
|
|
TEST_CHECK(ckd_sub == GUF_MATH_CKD_SUCCESS);
|
|
int8_t saturated;
|
|
TEST_CHECK(guf_saturating_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == sub_res);
|
|
int8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_sub_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == sub_res);
|
|
}
|
|
|
|
const int32_t mul_res = a * b;
|
|
const guf_math_ckd_result ckd_mul = guf_ckd_mul_i8((int8_t)a, (int8_t)b);
|
|
TEST_CHECK(ckd_mul == guf_ckd_mul_least_i8((int_least8_t)a, (int_least8_t)b));
|
|
TEST_CHECK(ckd_mul == guf_ckd_mul_i8((int8_t)b, (int8_t)a));
|
|
if (mul_res > INT8_MAX) {
|
|
TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_POS);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == INT8_MAX);
|
|
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
// TODO: check wrapped
|
|
} else if (mul_res < INT8_MIN) {
|
|
TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == INT8_MIN);
|
|
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
// TODO: check wrapped
|
|
} else {
|
|
TEST_CHECK(ckd_mul == GUF_MATH_CKD_SUCCESS);
|
|
int8_t saturated, saturated2;
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == mul_res);
|
|
|
|
TEST_CHECK(guf_saturating_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &saturated2) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(saturated == saturated2);
|
|
|
|
int8_t wrapped, wrapped2;
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(a), static_cast<int8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == mul_res);
|
|
TEST_CHECK(guf_wrapping_mul_i8(static_cast<int8_t>(b), static_cast<int8_t>(a), &wrapped2) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(wrapped == wrapped2);
|
|
}
|
|
}
|
|
}
|
|
|
|
int8_t mul_i8_res = -1;
|
|
TEST_CHECK(guf_wrapping_mul_i8(42, 5, &mul_i8_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i8_res == -46);
|
|
mul_i8_res = -1;
|
|
TEST_CHECK(guf_wrapping_mul_i8(5, 42, &mul_i8_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i8_res == -46);
|
|
|
|
int16_t mul_i16_res = -1245;
|
|
TEST_CHECK(guf_wrapping_mul_i16(32767, 2, &mul_i16_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i16_res == -2);
|
|
mul_i16_res = -1245;
|
|
TEST_CHECK(guf_wrapping_mul_i16(-32767, 2, &mul_i16_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(mul_i16_res == 2);
|
|
/*
|
|
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2024
|
|
|
|
use std::num::Wrapping;
|
|
|
|
fn main() {
|
|
let a = Wrapping(-314159265_i32);
|
|
let b = Wrapping(4096_i32);
|
|
println!("{}", a * b);
|
|
}
|
|
*/
|
|
|
|
int32_t mul_i32_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_i32(INT32_MAX, 2, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32_res == -2);
|
|
mul_i32_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_i32(2, INT32_MAX, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32_res == -2);
|
|
|
|
mul_i32_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_i32(INT32_MAX, -2, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(mul_i32_res == 2);
|
|
mul_i32_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_i32(-2, INT32_MAX, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(mul_i32_res == 2);
|
|
|
|
TEST_CHECK(guf_wrapping_mul_i32(42002718, 314159265, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32_res == -972735522);
|
|
mul_i32_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_i32(314159265, 42002718, &mul_i32_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32_res == -972735522);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(42002718, 314159265, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == -972735522);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(-42002718, 314159265, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == 972735522);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(-88888888, 99999999, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == 1374494264);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(INT32_MIN, -1, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == INT32_MIN);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(-2147483648, 2147483640, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == 0);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(-2048, -314159265, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == -846919680);
|
|
|
|
mul_i32_res = 12345;
|
|
guf_wrapping_mul_i32(4096, -314159265, &mul_i32_res);
|
|
TEST_CHECK(mul_i32_res == 1693839360);
|
|
|
|
|
|
int_least32_t mul_i32least_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(INT32_MAX, 2, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32least_res == -2);
|
|
mul_i32least_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(2, INT32_MAX, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32least_res == -2);
|
|
|
|
mul_i32least_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(INT32_MAX, -2, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(mul_i32least_res == 2);
|
|
mul_i32least_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(-2, INT32_MAX, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(mul_i32least_res == 2);
|
|
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(42002718, 314159265, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32least_res == -972735522);
|
|
mul_i32least_res = -12345;
|
|
TEST_CHECK(guf_wrapping_mul_least_i32(314159265, 42002718, &mul_i32least_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(mul_i32least_res == -972735522);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(42002718, 314159265, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == -972735522);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(-42002718, 314159265, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == 972735522);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(-88888888, 99999999, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == 1374494264);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(INT32_MIN, -1, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == INT32_MIN);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(-2147483648, 2147483640, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == 0);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(-2048, -314159265, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == -846919680);
|
|
|
|
mul_i32least_res = 12345;
|
|
guf_wrapping_mul_least_i32(4096, -314159265, &mul_i32least_res);
|
|
TEST_CHECK(mul_i32least_res == 1693839360);
|
|
|
|
|
|
|
|
ptrdiff_t ptrdiff_res = -1234;
|
|
TEST_CHECK(guf_saturating_add_ptrdiff_t(PTRDIFF_MAX, 1, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(ptrdiff_res == PTRDIFF_MAX);
|
|
ptrdiff_res = -1234;
|
|
TEST_CHECK(guf_saturating_add_ptrdiff_t(PTRDIFF_MIN, -1, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(ptrdiff_res == PTRDIFF_MIN);
|
|
|
|
ptrdiff_res = -1234;
|
|
TEST_CHECK(guf_saturating_mul_ptrdiff_t(PTRDIFF_MAX, 2, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(ptrdiff_res == PTRDIFF_MAX);
|
|
ptrdiff_res = -1234;
|
|
TEST_CHECK(guf_saturating_mul_ptrdiff_t(PTRDIFF_MIN, 2, &ptrdiff_res) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(ptrdiff_res == PTRDIFF_MIN);
|
|
}
|
|
|
|
void CkdIntTest::test_ckd_uint()
|
|
{
|
|
for (int32_t a = 0; a <= UINT8_MAX; ++a) {
|
|
for (int32_t b = 0; b <= UINT8_MAX; ++b) {
|
|
const int32_t add_res = a + b;
|
|
const guf_math_ckd_result ckd_add = guf_ckd_add_u8((uint8_t)a, (uint8_t)b);
|
|
GUF_ASSERT(ckd_add == guf_ckd_add_least_u8((uint_least8_t)a, (uint_least8_t)b));
|
|
if (add_res > UINT8_MAX) {
|
|
TEST_CHECK(ckd_add == GUF_MATH_CKD_OVERFLOW_POS);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_add_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == UINT8_MAX);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_add_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == 0 + (add_res % (UINT8_MAX + 1)));
|
|
}
|
|
else {
|
|
TEST_CHECK(ckd_add == GUF_MATH_CKD_SUCCESS);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_add_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == add_res);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_add_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == add_res);
|
|
}
|
|
|
|
const int32_t sub_res = a - b;
|
|
const guf_math_ckd_result ckd_sub = guf_ckd_sub_u8((uint8_t)a, (uint8_t)b);
|
|
GUF_ASSERT(ckd_sub == guf_ckd_sub_least_u8((uint_least8_t)a, (uint_least8_t)b));
|
|
if (sub_res < 0) {
|
|
TEST_CHECK(ckd_sub == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_sub_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(saturated == 0);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_sub_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_NEG);
|
|
TEST_CHECK(wrapped == static_cast<uint8_t>(static_cast<uint8_t>(a) - static_cast<uint8_t>(b)));
|
|
} else {
|
|
TEST_CHECK(ckd_sub == GUF_MATH_CKD_SUCCESS);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_sub_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == sub_res);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_sub_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == sub_res);
|
|
}
|
|
|
|
const int32_t mul_res = a * b;
|
|
const guf_math_ckd_result ckd_mul = guf_ckd_mul_u8((uint8_t)a, (uint8_t)b);
|
|
GUF_ASSERT(ckd_mul == guf_ckd_mul_least_u8((uint_least8_t)a, (uint_least8_t)b));
|
|
if (mul_res > UINT8_MAX) {
|
|
TEST_CHECK(ckd_mul == GUF_MATH_CKD_OVERFLOW_POS);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_mul_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(saturated == UINT8_MAX);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_mul_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_OVERFLOW_POS);
|
|
TEST_CHECK(wrapped == static_cast<uint8_t>(static_cast<uint8_t>(a) * static_cast<uint8_t>(b)));
|
|
} else {
|
|
TEST_CHECK(ckd_mul == GUF_MATH_CKD_SUCCESS);
|
|
uint8_t saturated;
|
|
TEST_CHECK(guf_saturating_mul_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &saturated) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(saturated) == mul_res);
|
|
uint8_t wrapped;
|
|
TEST_CHECK(guf_wrapping_mul_u8(static_cast<uint8_t>(a), static_cast<uint8_t>(b), &wrapped) == GUF_MATH_CKD_SUCCESS);
|
|
TEST_CHECK(static_cast<int32_t>(wrapped) == mul_res);
|
|
}
|
|
}
|
|
}
|
|
}
|