File size: 3,690 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
#include "../../unity/unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>

/* Helper: absolute value for long double without libm. */
static long double td_abs(long double v) { return v < 0 ? -v : v; }

/* Helper: assert two long doubles are close within absolute tolerance. */
static void assert_ld_close(long double expected, long double actual,
                            long double atol, const char *msg)
{
    long double diff = td_abs(actual - expected);
    if (diff > atol)
    {
        char buf[256];
        /* Use %Lg for long double and show high precision to aid debugging. */
        snprintf(buf, sizeof(buf), "%s Expected=%.21Lg Actual=%.21Lg Diff=%.21Lg Tol=%.21Lg",
                 msg ? msg : "", expected, actual, diff, atol);
        TEST_FAIL_MESSAGE(buf);
    }
}

void setUp(void) {
    /* No setup needed for powerld */
}

void tearDown(void) {
    /* No teardown needed */
}

/* Target under test: static long double powerld(long double base, int x); */

void test_powerld_zero_exponent_returns_one_for_various_bases(void)
{
    const long double tol = 1e-18L;
    assert_ld_close(1.0L, powerld(2.0L, 0), tol, "2^0 should be 1");
    assert_ld_close(1.0L, powerld(-3.5L, 0), tol, "(-3.5)^0 should be 1");
    assert_ld_close(1.0L, powerld(0.0L, 0), tol, "0^0 returns 1 by implementation");
    assert_ld_close(1.0L, powerld(1.0L, 0), tol, "1^0 should be 1");
}

void test_powerld_exponent_one_returns_base(void)
{
    const long double tol = 1e-18L;
    assert_ld_close(2.0L, powerld(2.0L, 1), tol, "2^1 should be 2");
    assert_ld_close(-7.25L, powerld(-7.25L, 1), tol, "(-7.25)^1 should be -7.25");
    assert_ld_close(0.125L, powerld(0.125L, 1), tol, "0.125^1 should be 0.125");
}

void test_powerld_integer_bases_and_exponents(void)
{
    const long double tol = 1e-18L;
    assert_ld_close(1024.0L, powerld(2.0L, 10), tol, "2^10 should be 1024");
    assert_ld_close(1000.0L, powerld(10.0L, 3), tol, "10^3 should be 1000");
    assert_ld_close(81.0L, powerld(3.0L, 4), tol, "3^4 should be 81");
    assert_ld_close(0.0L, powerld(0.0L, 5), tol, "0^5 should be 0");
}

void test_powerld_fractional_bases(void)
{
    const long double tol = 1e-15L; /* slightly looser for fractional accumulations */
    assert_ld_close(3.375L, powerld(1.5L, 3), tol, "1.5^3 should be 3.375");
    assert_ld_close(0.01L, powerld(0.1L, 2), 1e-18L, "0.1^2 should be 0.01");
    assert_ld_close(0.25L, powerld(0.5L, 2), 1e-18L, "0.5^2 should be 0.25");
}

void test_powerld_negative_bases_even_odd_exponents(void)
{
    const long double tol = 1e-18L;
    assert_ld_close(-8.0L, powerld(-2.0L, 3), tol, "(-2)^3 should be -8");
    assert_ld_close(16.0L, powerld(-2.0L, 4), tol, "(-2)^4 should be 16");
    assert_ld_close(0.25L, powerld(-0.5L, 2), tol, "(-0.5)^2 should be 0.25");
}

void test_powerld_identities_one_and_zero_bases(void)
{
    const long double tol = 1e-18L;
    /* 1^x == 1 for nonnegative integer x */
    assert_ld_close(1.0L, powerld(1.0L, 5), tol, "1^5 should be 1");
    assert_ld_close(1.0L, powerld(1.0L, 100), tol, "1^100 should be 1");

    /* 0^x == 0 for x>0 */
    assert_ld_close(0.0L, powerld(0.0L, 1), tol, "0^1 should be 0");
    assert_ld_close(0.0L, powerld(0.0L, 10), tol, "0^10 should be 0");
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_powerld_zero_exponent_returns_one_for_various_bases);
    RUN_TEST(test_powerld_exponent_one_returns_base);
    RUN_TEST(test_powerld_integer_bases_and_exponents);
    RUN_TEST(test_powerld_fractional_bases);
    RUN_TEST(test_powerld_negative_bases_even_odd_exponents);
    RUN_TEST(test_powerld_identities_one_and_zero_bases);
    return UNITY_END();
}