coreutils / tests /numfmt /tests_for_expld.c
AryaWu's picture
Upload folder using huggingface_hub
78d2150 verified
#include "../../unity/unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
/* Helper: absolute value for long double without libm dependency */
static long double ldabs(long double x) { return x < 0 ? -x : x; }
/* Helper: assert two long doubles are approximately equal */
static void assert_ld_close(long double expected, long double actual, long double tol, const char* msg)
{
long double diff = ldabs(expected - actual);
if (diff > tol)
{
char buf[256];
snprintf(buf, sizeof(buf),
"%s: expected %.18Lg but got %.18Lg (diff=%.18Lg, tol=%.18Lg)",
msg ? msg : "Mismatch", expected, actual, diff, tol);
TEST_FAIL_MESSAGE(buf);
}
}
/* Unity fixtures */
void setUp(void) {
/* no global state to set for expld() */
}
void tearDown(void) {
/* nothing to clean up */
}
/* Tests */
static void test_expld_abs_less_than_base(void)
{
int x = -1;
long double in = 9.5L;
long double out = expld(in, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, x, "power should be 0 when |val| < base");
assert_ld_close(in, out, 1e-15L, "value should be unchanged when |val| < base");
}
static void test_expld_exact_power_of_base(void)
{
int x = -1;
long double in = 1000.0L; /* 10^3 */
long double out = expld(in, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(3, x, "power should be 3 for 10^3");
assert_ld_close(1.0L, out, 1e-18L, "scaled value should be 1.0 for 10^3");
}
static void test_expld_negative_value(void)
{
int x = -1;
long double in = -12345.0L;
long double out = expld(in, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(4, x, "power should be 4 for |-12345|");
/* Expected: -1.2345 */
assert_ld_close(-1.2345L, out, 1e-15L, "scaled value mismatch for negative input");
}
static void test_expld_base_1024_exact(void)
{
int x = -1;
long double in = 5.0L * powerld(1024.0L, 2); /* 5 * 1024^2 */
long double out = expld(in, 1024, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(2, x, "power should be 2 for 5*1024^2");
assert_ld_close(5.0L, out, 1e-18L, "scaled value should be exactly 5.0");
}
static void test_expld_zero_value(void)
{
int x = -1;
long double out = expld(0.0L, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, x, "power should be 0 for input 0");
assert_ld_close(0.0L, out, 0.0L, "output should be 0 for input 0");
}
static void test_expld_null_x_pointer(void)
{
long double in = 2048.0L; /* 2 * 1024 */
long double out = expld(in, 1024, NULL);
/* Should scale to 2.0, but we cannot check x as it's NULL; ensure no crash and correct value */
assert_ld_close(2.0L, out, 1e-18L, "scaled value should be 2.0 when x is NULL");
}
static void test_expld_fractional_scaling_and_reversibility(void)
{
int x = -1;
long double base = 10.0L;
int k = 6;
long double mantissa = 7.25L;
long double in = mantissa * powerld(base, k); /* 7.25e6 */
long double out = expld(in, (int)base, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(k, x, "power should equal the constructed exponent");
assert_ld_close(mantissa, out, 1e-12L, "scaled mantissa mismatch");
/* Verify |out| < base and reconstruction property approximately holds */
TEST_ASSERT_TRUE_MESSAGE(ldabs(out) < base, "|scaled value| should be < base");
long double recon = out;
for (int i = 0; i < x; i++) recon *= base;
/* Use relative tolerance for large numbers */
long double rel_tol = 1e-12L;
long double tol = ldabs(in) * rel_tol + 1e-6L;
assert_ld_close(in, recon, tol, "reconstructed value mismatch");
}
static void test_expld_fractional_input_base10(void)
{
int x = -1;
long double in = 123.456L;
long double out = expld(in, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(2, x, "power should be 2 for 123.456 with base 10");
assert_ld_close(1.23456L, out, 1e-15L, "scaled value mismatch for 123.456");
}
static void test_expld_nan_input_sets_x_zero_and_returns_nan(void)
{
int x = -1;
long double nanval = (long double)NAN;
long double out = expld(nanval, 10, &x);
TEST_ASSERT_EQUAL_INT_MESSAGE(0, x, "power should be 0 for NaN input");
TEST_ASSERT_TRUE_MESSAGE(out != out, "output should be NaN (NaN != NaN)");
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_expld_abs_less_than_base);
RUN_TEST(test_expld_exact_power_of_base);
RUN_TEST(test_expld_negative_value);
RUN_TEST(test_expld_base_1024_exact);
RUN_TEST(test_expld_zero_value);
RUN_TEST(test_expld_null_x_pointer);
RUN_TEST(test_expld_fractional_scaling_and_reversibility);
RUN_TEST(test_expld_fractional_input_base10);
RUN_TEST(test_expld_nan_input_sets_x_zero_and_returns_nan);
return UNITY_END();
}