AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdint.h>4#include <limits.h>5#include <string.h>6 7/* Wrapper for the static function under test (provided in module) */8extern void test_kahanBabuskaNeumaierInit(volatile SumCtx *p, i64 iVal);9 10static const i64 TWO_POW_52 = 4503599627370496LL; /* 2^52 */11static const i64 MOD_16384 = 16384;12 13/* Unity required hooks */14void setUp(void) {15 /* no-op */16}17void tearDown(void) {18 /* no-op */19}20 21/* Helper to run the initializer and check expected results */22static void check_expected(i64 iVal, double expected_rSum, double expected_rErr){23 SumCtx s;24 memset(&s, 0xAA, sizeof(s)); /* poison so function must overwrite */25 test_kahanBabuskaNeumaierInit(&s, iVal);26 TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected_rSum, s.rSum, "rSum mismatch");27 TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected_rErr, s.rErr, "rErr mismatch");28}29 30/* Helper to compute the expected result per the documented logic */31static void compute_and_check(i64 iVal){32 double expected_rSum, expected_rErr;33 if( iVal <= -TWO_POW_52 || iVal >= +TWO_POW_52 ){34 i64 iSm = iVal % MOD_16384;35 expected_rSum = (double)(iVal - iSm);36 expected_rErr = (double)iSm;37 }else{38 expected_rSum = (double)iVal;39 expected_rErr = 0.0;40 }41 check_expected(iVal, expected_rSum, expected_rErr);42}43 44/* Tests start here */45 46void test_kahanBabuskaNeumaierInit_within_threshold_small_values(void){47 compute_and_check(0);48 compute_and_check(1);49 compute_and_check(-1);50 compute_and_check(TWO_POW_52 - 1); /* just below +2^52 */51 compute_and_check(-(TWO_POW_52 - 1)); /* just above -2^52 */52}53 54void test_kahanBabuskaNeumaierInit_at_threshold_values(void){55 /* Exactly at +/- 2^52: remainder is 0 because it's a multiple of 16384 */56 compute_and_check(TWO_POW_52);57 compute_and_check(-TWO_POW_52);58}59 60void test_kahanBabuskaNeumaierInit_above_threshold_with_nonzero_remainder_positive(void){61 /* Non-zero remainders trigger split into rSum and rErr */62 i64 v1 = TWO_POW_52 + 1; /* remainder 1 */63 i64 v2 = TWO_POW_52 + 16385; /* remainder 1 again (16385 % 16384) */64 i64 v3 = TWO_POW_52 + 12345; /* general non-zero remainder */65 compute_and_check(v1);66 compute_and_check(v2);67 compute_and_check(v3);68}69 70void test_kahanBabuskaNeumaierInit_below_threshold_with_nonzero_remainder_negative(void){71 /* For negatives, C % retains sign of dividend -> negative remainders */72 i64 v1 = -TWO_POW_52 - 1; /* remainder -1 */73 i64 v2 = -TWO_POW_52 - 16385; /* remainder -1 */74 i64 v3 = -TWO_POW_52 - 12345; /* general negative remainder */75 compute_and_check(v1);76 compute_and_check(v2);77 compute_and_check(v3);78}79 80void test_kahanBabuskaNeumaierInit_large_multiples_of_16384_have_zero_remainder(void){81 /* Values that are multiples of 16384 yield rErr == 0 */82 i64 v1 = TWO_POW_52; /* multiple of 16384 */83 i64 v2 = TWO_POW_52 + MOD_16384; /* still a multiple of 16384 */84 i64 v3 = -TWO_POW_52; /* negative multiple */85 i64 v4 = -TWO_POW_52 - MOD_16384; /* negative multiple offset */86 compute_and_check(v1);87 compute_and_check(v2);88 compute_and_check(v3);89 compute_and_check(v4);90}91 92void test_kahanBabuskaNeumaierInit_extreme_64bit_values(void){93 /* Ensure modulo and splitting behave at int64 extremes */94 compute_and_check(LLONG_MAX);95 compute_and_check(LLONG_MIN);96}97 98int main(void){99 UNITY_BEGIN();100 RUN_TEST(test_kahanBabuskaNeumaierInit_within_threshold_small_values);101 RUN_TEST(test_kahanBabuskaNeumaierInit_at_threshold_values);102 RUN_TEST(test_kahanBabuskaNeumaierInit_above_threshold_with_nonzero_remainder_positive);103 RUN_TEST(test_kahanBabuskaNeumaierInit_below_threshold_with_nonzero_remainder_negative);104 RUN_TEST(test_kahanBabuskaNeumaierInit_large_multiples_of_16384_have_zero_remainder);105 RUN_TEST(test_kahanBabuskaNeumaierInit_extreme_64bit_values);106 return UNITY_END();107}