#include "../../unity/unity.h" #include #include #include /* Unity fixtures */ void setUp(void) { /* no setup needed */ } void tearDown(void) { /* no teardown needed */ } /* Helper to assert long double equality for integer results */ static void assert_ld_equal(long double expected, long double actual, const char* msg) { if (!(expected == actual)) { char buf[256]; /* Print with no fractional digits as results are integral */ snprintf(buf, sizeof(buf), "%s: expected %.0Lf got %.0Lf", msg, expected, actual); TEST_FAIL_MESSAGE(buf); } } /* Convenience: get INTMAX_MAX as long double */ static long double LDMAX(void) { return (long double)INTMAX_MAX; } /* Basic rounding tests for small values */ void test_simple_round_ceiling_basic(void) { TEST_ASSERT_EQUAL_INT(2, (int)simple_round(1.1L, round_ceiling)); TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.0L, round_ceiling)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.1L, round_ceiling)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.0L, round_ceiling)); } void test_simple_round_floor_basic(void) { TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.9L, round_floor)); TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.0L, round_floor)); TEST_ASSERT_EQUAL_INT(-2, (int)simple_round(-1.1L, round_floor)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.0L, round_floor)); } void test_simple_round_from_zero_basic(void) { TEST_ASSERT_EQUAL_INT(2, (int)simple_round(1.1L, round_from_zero)); TEST_ASSERT_EQUAL_INT(-2, (int)simple_round(-1.1L, round_from_zero)); TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.0L, round_from_zero)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.0L, round_from_zero)); } void test_simple_round_to_zero_basic(void) { TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.9L, round_to_zero)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.9L, round_to_zero)); TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.0L, round_to_zero)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.0L, round_to_zero)); } void test_simple_round_nearest_basic(void) { TEST_ASSERT_EQUAL_INT(1, (int)simple_round(1.49L, round_nearest)); TEST_ASSERT_EQUAL_INT(2, (int)simple_round(1.5L, round_nearest)); TEST_ASSERT_EQUAL_INT(-1, (int)simple_round(-1.49L, round_nearest)); TEST_ASSERT_EQUAL_INT(-2, (int)simple_round(-1.5L, round_nearest)); } /* Boundary behavior around INTMAX_MAX using 0.5 which is representable */ void test_simple_round_near_INTMAX_MAX_ceil_floor(void) { long double M = LDMAX(); /* M - 0.5 */ long double v1 = M - 0.5L; long double ceil_v1 = simple_round(v1, round_ceiling); long double floor_v1 = simple_round(v1, round_floor); assert_ld_equal(M, ceil_v1, "ceil(M-0.5)"); assert_ld_equal(M - 1.0L, floor_v1, "floor(M-0.5)"); /* M + 0.5 */ long double v2 = M + 0.5L; long double ceil_v2 = simple_round(v2, round_ceiling); long double floor_v2 = simple_round(v2, round_floor); assert_ld_equal(M + 1.0L, ceil_v2, "ceil(M+0.5)"); assert_ld_equal(M, floor_v2, "floor(M+0.5)"); } void test_simple_round_near_INTMAX_MAX_from_to_zero(void) { long double M = LDMAX(); /* Positive side */ long double vp = M + 0.5L; assert_ld_equal(M + 1.0L, simple_round(vp, round_from_zero), "from_zero(M+0.5)"); assert_ld_equal(M, simple_round(vp, round_to_zero), "to_zero(M+0.5)"); /* Negative side */ long double vn = -(M + 0.5L); assert_ld_equal(-(M + 1.0L), simple_round(vn, round_from_zero), "from_zero(-(M+0.5))"); assert_ld_equal(-M, simple_round(vn, round_to_zero), "to_zero(-(M+0.5))"); } void test_simple_round_near_INTMAX_MAX_nearest(void) { long double M = LDMAX(); /* .5 ties away from zero */ assert_ld_equal(M + 1.0L, simple_round(M + 0.5L, round_nearest), "nearest(M+0.5)"); assert_ld_equal(- (M + 1.0L), simple_round(- (M + 0.5L), round_nearest), "nearest(-(M+0.5))"); /* Below half goes to nearest integer */ assert_ld_equal(M, simple_round(M + 0.49L, round_nearest), "nearest(M+0.49)"); assert_ld_equal(-M, simple_round(- (M + 0.49L), round_nearest), "nearest(-(M+0.49))"); } /* Large values exercising partitioning logic with multiples of INTMAX_MAX */ void test_simple_round_large_exact_multiples(void) { long double M = LDMAX(); /* Exactly 2*M */ long double v = 2.0L * M; assert_ld_equal(2.0L * M, simple_round(v, round_ceiling), "ceil(2*M)"); assert_ld_equal(2.0L * M, simple_round(v, round_floor), "floor(2*M)"); assert_ld_equal(2.0L * M, simple_round(v, round_from_zero), "from_zero(2*M)"); assert_ld_equal(2.0L * M, simple_round(v, round_to_zero), "to_zero(2*M)"); assert_ld_equal(2.0L * M, simple_round(v, round_nearest), "nearest(2*M)"); /* 2*M + 1 (still an integer) */ long double v2 = 2.0L * M + 1.0L; assert_ld_equal(2.0L * M + 1.0L, simple_round(v2, round_ceiling), "ceil(2*M+1)"); assert_ld_equal(2.0L * M + 1.0L, simple_round(v2, round_floor), "floor(2*M+1)"); assert_ld_equal(2.0L * M + 1.0L, simple_round(v2, round_from_zero), "from_zero(2*M+1)"); assert_ld_equal(2.0L * M + 1.0L, simple_round(v2, round_to_zero), "to_zero(2*M+1)"); assert_ld_equal(2.0L * M + 1.0L, simple_round(v2, round_nearest), "nearest(2*M+1)"); /* Negative exact large values */ long double vn = - (2.0L * M); assert_ld_equal(- (2.0L * M), simple_round(vn, round_ceiling), "ceil(-2*M)"); assert_ld_equal(- (2.0L * M), simple_round(vn, round_floor), "floor(-2*M)"); assert_ld_equal(- (2.0L * M), simple_round(vn, round_from_zero), "from_zero(-2*M)"); assert_ld_equal(- (2.0L * M), simple_round(vn, round_to_zero), "to_zero(-2*M)"); assert_ld_equal(- (2.0L * M), simple_round(vn, round_nearest), "nearest(-2*M)"); } /* Zero edge cases */ void test_simple_round_zero_cases(void) { TEST_ASSERT_EQUAL_INT(0, (int)simple_round(0.0L, round_ceiling)); TEST_ASSERT_EQUAL_INT(0, (int)simple_round(0.0L, round_floor)); TEST_ASSERT_EQUAL_INT(0, (int)simple_round(0.0L, round_from_zero)); TEST_ASSERT_EQUAL_INT(0, (int)simple_round(0.0L, round_to_zero)); TEST_ASSERT_EQUAL_INT(0, (int)simple_round(0.0L, round_nearest)); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_simple_round_ceiling_basic); RUN_TEST(test_simple_round_floor_basic); RUN_TEST(test_simple_round_from_zero_basic); RUN_TEST(test_simple_round_to_zero_basic); RUN_TEST(test_simple_round_nearest_basic); RUN_TEST(test_simple_round_near_INTMAX_MAX_ceil_floor); RUN_TEST(test_simple_round_near_INTMAX_MAX_from_to_zero); RUN_TEST(test_simple_round_near_INTMAX_MAX_nearest); RUN_TEST(test_simple_round_large_exact_multiples); RUN_TEST(test_simple_round_zero_cases); return UNITY_END(); }