#include "../../unity/unity.h" #include #include #include #include /* 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(); }