File size: 6,735 Bytes
78d2150 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
#include "../../unity/unity.h"
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
/* 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();
} |