1*7bdf38e5Schristos #include "test/jemalloc_test.h" 2*7bdf38e5Schristos 3*7bdf38e5Schristos #include "jemalloc/internal/fxp.h" 4*7bdf38e5Schristos 5*7bdf38e5Schristos static double 6*7bdf38e5Schristos fxp2double(fxp_t a) { 7*7bdf38e5Schristos double intpart = (double)(a >> 16); 8*7bdf38e5Schristos double fracpart = (double)(a & ((1U << 16) - 1)) / (1U << 16); 9*7bdf38e5Schristos return intpart + fracpart; 10*7bdf38e5Schristos } 11*7bdf38e5Schristos 12*7bdf38e5Schristos /* Is a close to b? */ 13*7bdf38e5Schristos static bool 14*7bdf38e5Schristos double_close(double a, double b) { 15*7bdf38e5Schristos /* 16*7bdf38e5Schristos * Our implementation doesn't try for precision. Correspondingly, don't 17*7bdf38e5Schristos * enforce it too strenuously here; accept values that are close in 18*7bdf38e5Schristos * either relative or absolute terms. 19*7bdf38e5Schristos */ 20*7bdf38e5Schristos return fabs(a - b) < 0.01 || fabs(a - b) / a < 0.01; 21*7bdf38e5Schristos } 22*7bdf38e5Schristos 23*7bdf38e5Schristos static bool 24*7bdf38e5Schristos fxp_close(fxp_t a, fxp_t b) { 25*7bdf38e5Schristos return double_close(fxp2double(a), fxp2double(b)); 26*7bdf38e5Schristos } 27*7bdf38e5Schristos 28*7bdf38e5Schristos static fxp_t 29*7bdf38e5Schristos xparse_fxp(const char *str) { 30*7bdf38e5Schristos fxp_t result; 31*7bdf38e5Schristos bool err = fxp_parse(&result, str, NULL); 32*7bdf38e5Schristos assert_false(err, "Invalid fxp string: %s", str); 33*7bdf38e5Schristos return result; 34*7bdf38e5Schristos } 35*7bdf38e5Schristos 36*7bdf38e5Schristos static void 37*7bdf38e5Schristos expect_parse_accurate(const char *str, const char *parse_str) { 38*7bdf38e5Schristos double true_val = strtod(str, NULL); 39*7bdf38e5Schristos fxp_t fxp_val; 40*7bdf38e5Schristos char *end; 41*7bdf38e5Schristos bool err = fxp_parse(&fxp_val, parse_str, &end); 42*7bdf38e5Schristos expect_false(err, "Unexpected parse failure"); 43*7bdf38e5Schristos expect_ptr_eq(parse_str + strlen(str), end, 44*7bdf38e5Schristos "Didn't parse whole string"); 45*7bdf38e5Schristos expect_true(double_close(fxp2double(fxp_val), true_val), 46*7bdf38e5Schristos "Misparsed %s", str); 47*7bdf38e5Schristos } 48*7bdf38e5Schristos 49*7bdf38e5Schristos static void 50*7bdf38e5Schristos parse_valid_trial(const char *str) { 51*7bdf38e5Schristos /* The value it parses should be correct. */ 52*7bdf38e5Schristos expect_parse_accurate(str, str); 53*7bdf38e5Schristos char buf[100]; 54*7bdf38e5Schristos snprintf(buf, sizeof(buf), "%swith_some_trailing_text", str); 55*7bdf38e5Schristos expect_parse_accurate(str, buf); 56*7bdf38e5Schristos snprintf(buf, sizeof(buf), "%s with a space", str); 57*7bdf38e5Schristos expect_parse_accurate(str, buf); 58*7bdf38e5Schristos snprintf(buf, sizeof(buf), "%s,in_a_malloc_conf_string:1", str); 59*7bdf38e5Schristos expect_parse_accurate(str, buf); 60*7bdf38e5Schristos } 61*7bdf38e5Schristos 62*7bdf38e5Schristos TEST_BEGIN(test_parse_valid) { 63*7bdf38e5Schristos parse_valid_trial("0"); 64*7bdf38e5Schristos parse_valid_trial("1"); 65*7bdf38e5Schristos parse_valid_trial("2"); 66*7bdf38e5Schristos parse_valid_trial("100"); 67*7bdf38e5Schristos parse_valid_trial("345"); 68*7bdf38e5Schristos parse_valid_trial("00000000123"); 69*7bdf38e5Schristos parse_valid_trial("00000000987"); 70*7bdf38e5Schristos 71*7bdf38e5Schristos parse_valid_trial("0.0"); 72*7bdf38e5Schristos parse_valid_trial("0.00000000000456456456"); 73*7bdf38e5Schristos parse_valid_trial("100.00000000000456456456"); 74*7bdf38e5Schristos 75*7bdf38e5Schristos parse_valid_trial("123.1"); 76*7bdf38e5Schristos parse_valid_trial("123.01"); 77*7bdf38e5Schristos parse_valid_trial("123.001"); 78*7bdf38e5Schristos parse_valid_trial("123.0001"); 79*7bdf38e5Schristos parse_valid_trial("123.00001"); 80*7bdf38e5Schristos parse_valid_trial("123.000001"); 81*7bdf38e5Schristos parse_valid_trial("123.0000001"); 82*7bdf38e5Schristos 83*7bdf38e5Schristos parse_valid_trial(".0"); 84*7bdf38e5Schristos parse_valid_trial(".1"); 85*7bdf38e5Schristos parse_valid_trial(".01"); 86*7bdf38e5Schristos parse_valid_trial(".001"); 87*7bdf38e5Schristos parse_valid_trial(".0001"); 88*7bdf38e5Schristos parse_valid_trial(".00001"); 89*7bdf38e5Schristos parse_valid_trial(".000001"); 90*7bdf38e5Schristos 91*7bdf38e5Schristos parse_valid_trial(".1"); 92*7bdf38e5Schristos parse_valid_trial(".10"); 93*7bdf38e5Schristos parse_valid_trial(".100"); 94*7bdf38e5Schristos parse_valid_trial(".1000"); 95*7bdf38e5Schristos parse_valid_trial(".100000"); 96*7bdf38e5Schristos } 97*7bdf38e5Schristos TEST_END 98*7bdf38e5Schristos 99*7bdf38e5Schristos static void 100*7bdf38e5Schristos expect_parse_failure(const char *str) { 101*7bdf38e5Schristos fxp_t result = FXP_INIT_INT(333); 102*7bdf38e5Schristos char *end = (void *)0x123; 103*7bdf38e5Schristos bool err = fxp_parse(&result, str, &end); 104*7bdf38e5Schristos expect_true(err, "Expected a parse error on: %s", str); 105*7bdf38e5Schristos expect_ptr_eq((void *)0x123, end, 106*7bdf38e5Schristos "Parse error shouldn't change results"); 107*7bdf38e5Schristos expect_u32_eq(result, FXP_INIT_INT(333), 108*7bdf38e5Schristos "Parse error shouldn't change results"); 109*7bdf38e5Schristos } 110*7bdf38e5Schristos 111*7bdf38e5Schristos TEST_BEGIN(test_parse_invalid) { 112*7bdf38e5Schristos expect_parse_failure("123."); 113*7bdf38e5Schristos expect_parse_failure("3.a"); 114*7bdf38e5Schristos expect_parse_failure(".a"); 115*7bdf38e5Schristos expect_parse_failure("a.1"); 116*7bdf38e5Schristos expect_parse_failure("a"); 117*7bdf38e5Schristos /* A valid string, but one that overflows. */ 118*7bdf38e5Schristos expect_parse_failure("123456789"); 119*7bdf38e5Schristos expect_parse_failure("0000000123456789"); 120*7bdf38e5Schristos expect_parse_failure("1000000"); 121*7bdf38e5Schristos } 122*7bdf38e5Schristos TEST_END 123*7bdf38e5Schristos 124*7bdf38e5Schristos static void 125*7bdf38e5Schristos expect_init_percent(unsigned percent, const char *str) { 126*7bdf38e5Schristos fxp_t result_init = FXP_INIT_PERCENT(percent); 127*7bdf38e5Schristos fxp_t result_parse = xparse_fxp(str); 128*7bdf38e5Schristos expect_u32_eq(result_init, result_parse, 129*7bdf38e5Schristos "Expect representations of FXP_INIT_PERCENT(%u) and " 130*7bdf38e5Schristos "fxp_parse(\"%s\") to be equal; got %x and %x", 131*7bdf38e5Schristos percent, str, result_init, result_parse); 132*7bdf38e5Schristos 133*7bdf38e5Schristos } 134*7bdf38e5Schristos 135*7bdf38e5Schristos /* 136*7bdf38e5Schristos * Every other test uses either parsing or FXP_INIT_INT; it gets tested in those 137*7bdf38e5Schristos * ways. We need a one-off for the percent-based initialization, though. 138*7bdf38e5Schristos */ 139*7bdf38e5Schristos TEST_BEGIN(test_init_percent) { 140*7bdf38e5Schristos expect_init_percent(100, "1"); 141*7bdf38e5Schristos expect_init_percent(75, ".75"); 142*7bdf38e5Schristos expect_init_percent(1, ".01"); 143*7bdf38e5Schristos expect_init_percent(50, ".5"); 144*7bdf38e5Schristos } 145*7bdf38e5Schristos TEST_END 146*7bdf38e5Schristos 147*7bdf38e5Schristos static void 148*7bdf38e5Schristos expect_add(const char *astr, const char *bstr, const char* resultstr) { 149*7bdf38e5Schristos fxp_t a = xparse_fxp(astr); 150*7bdf38e5Schristos fxp_t b = xparse_fxp(bstr); 151*7bdf38e5Schristos fxp_t result = xparse_fxp(resultstr); 152*7bdf38e5Schristos expect_true(fxp_close(fxp_add(a, b), result), 153*7bdf38e5Schristos "Expected %s + %s == %s", astr, bstr, resultstr); 154*7bdf38e5Schristos } 155*7bdf38e5Schristos 156*7bdf38e5Schristos TEST_BEGIN(test_add_simple) { 157*7bdf38e5Schristos expect_add("0", "0", "0"); 158*7bdf38e5Schristos expect_add("0", "1", "1"); 159*7bdf38e5Schristos expect_add("1", "1", "2"); 160*7bdf38e5Schristos expect_add("1.5", "1.5", "3"); 161*7bdf38e5Schristos expect_add("0.1", "0.1", "0.2"); 162*7bdf38e5Schristos expect_add("123", "456", "579"); 163*7bdf38e5Schristos } 164*7bdf38e5Schristos TEST_END 165*7bdf38e5Schristos 166*7bdf38e5Schristos static void 167*7bdf38e5Schristos expect_sub(const char *astr, const char *bstr, const char* resultstr) { 168*7bdf38e5Schristos fxp_t a = xparse_fxp(astr); 169*7bdf38e5Schristos fxp_t b = xparse_fxp(bstr); 170*7bdf38e5Schristos fxp_t result = xparse_fxp(resultstr); 171*7bdf38e5Schristos expect_true(fxp_close(fxp_sub(a, b), result), 172*7bdf38e5Schristos "Expected %s - %s == %s", astr, bstr, resultstr); 173*7bdf38e5Schristos } 174*7bdf38e5Schristos 175*7bdf38e5Schristos TEST_BEGIN(test_sub_simple) { 176*7bdf38e5Schristos expect_sub("0", "0", "0"); 177*7bdf38e5Schristos expect_sub("1", "0", "1"); 178*7bdf38e5Schristos expect_sub("1", "1", "0"); 179*7bdf38e5Schristos expect_sub("3.5", "1.5", "2"); 180*7bdf38e5Schristos expect_sub("0.3", "0.1", "0.2"); 181*7bdf38e5Schristos expect_sub("456", "123", "333"); 182*7bdf38e5Schristos } 183*7bdf38e5Schristos TEST_END 184*7bdf38e5Schristos 185*7bdf38e5Schristos static void 186*7bdf38e5Schristos expect_mul(const char *astr, const char *bstr, const char* resultstr) { 187*7bdf38e5Schristos fxp_t a = xparse_fxp(astr); 188*7bdf38e5Schristos fxp_t b = xparse_fxp(bstr); 189*7bdf38e5Schristos fxp_t result = xparse_fxp(resultstr); 190*7bdf38e5Schristos expect_true(fxp_close(fxp_mul(a, b), result), 191*7bdf38e5Schristos "Expected %s * %s == %s", astr, bstr, resultstr); 192*7bdf38e5Schristos } 193*7bdf38e5Schristos 194*7bdf38e5Schristos TEST_BEGIN(test_mul_simple) { 195*7bdf38e5Schristos expect_mul("0", "0", "0"); 196*7bdf38e5Schristos expect_mul("1", "0", "0"); 197*7bdf38e5Schristos expect_mul("1", "1", "1"); 198*7bdf38e5Schristos expect_mul("1.5", "1.5", "2.25"); 199*7bdf38e5Schristos expect_mul("100.0", "10", "1000"); 200*7bdf38e5Schristos expect_mul(".1", "10", "1"); 201*7bdf38e5Schristos } 202*7bdf38e5Schristos TEST_END 203*7bdf38e5Schristos 204*7bdf38e5Schristos static void 205*7bdf38e5Schristos expect_div(const char *astr, const char *bstr, const char* resultstr) { 206*7bdf38e5Schristos fxp_t a = xparse_fxp(astr); 207*7bdf38e5Schristos fxp_t b = xparse_fxp(bstr); 208*7bdf38e5Schristos fxp_t result = xparse_fxp(resultstr); 209*7bdf38e5Schristos expect_true(fxp_close(fxp_div(a, b), result), 210*7bdf38e5Schristos "Expected %s / %s == %s", astr, bstr, resultstr); 211*7bdf38e5Schristos } 212*7bdf38e5Schristos 213*7bdf38e5Schristos TEST_BEGIN(test_div_simple) { 214*7bdf38e5Schristos expect_div("1", "1", "1"); 215*7bdf38e5Schristos expect_div("0", "1", "0"); 216*7bdf38e5Schristos expect_div("2", "1", "2"); 217*7bdf38e5Schristos expect_div("3", "2", "1.5"); 218*7bdf38e5Schristos expect_div("3", "1.5", "2"); 219*7bdf38e5Schristos expect_div("10", ".1", "100"); 220*7bdf38e5Schristos expect_div("123", "456", ".2697368421"); 221*7bdf38e5Schristos } 222*7bdf38e5Schristos TEST_END 223*7bdf38e5Schristos 224*7bdf38e5Schristos static void 225*7bdf38e5Schristos expect_round(const char *str, uint32_t rounded_down, uint32_t rounded_nearest) { 226*7bdf38e5Schristos fxp_t fxp = xparse_fxp(str); 227*7bdf38e5Schristos uint32_t fxp_rounded_down = fxp_round_down(fxp); 228*7bdf38e5Schristos uint32_t fxp_rounded_nearest = fxp_round_nearest(fxp); 229*7bdf38e5Schristos expect_u32_eq(rounded_down, fxp_rounded_down, 230*7bdf38e5Schristos "Mistake rounding %s down", str); 231*7bdf38e5Schristos expect_u32_eq(rounded_nearest, fxp_rounded_nearest, 232*7bdf38e5Schristos "Mistake rounding %s to nearest", str); 233*7bdf38e5Schristos } 234*7bdf38e5Schristos 235*7bdf38e5Schristos TEST_BEGIN(test_round_simple) { 236*7bdf38e5Schristos expect_round("1.5", 1, 2); 237*7bdf38e5Schristos expect_round("0", 0, 0); 238*7bdf38e5Schristos expect_round("0.1", 0, 0); 239*7bdf38e5Schristos expect_round("0.4", 0, 0); 240*7bdf38e5Schristos expect_round("0.40000", 0, 0); 241*7bdf38e5Schristos expect_round("0.5", 0, 1); 242*7bdf38e5Schristos expect_round("0.6", 0, 1); 243*7bdf38e5Schristos expect_round("123", 123, 123); 244*7bdf38e5Schristos expect_round("123.4", 123, 123); 245*7bdf38e5Schristos expect_round("123.5", 123, 124); 246*7bdf38e5Schristos } 247*7bdf38e5Schristos TEST_END 248*7bdf38e5Schristos 249*7bdf38e5Schristos static void 250*7bdf38e5Schristos expect_mul_frac(size_t a, const char *fracstr, size_t expected) { 251*7bdf38e5Schristos fxp_t frac = xparse_fxp(fracstr); 252*7bdf38e5Schristos size_t result = fxp_mul_frac(a, frac); 253*7bdf38e5Schristos expect_true(double_close(expected, result), 254*7bdf38e5Schristos "Expected %zu * %s == %zu (fracmul); got %zu", a, fracstr, 255*7bdf38e5Schristos expected, result); 256*7bdf38e5Schristos } 257*7bdf38e5Schristos 258*7bdf38e5Schristos TEST_BEGIN(test_mul_frac_simple) { 259*7bdf38e5Schristos expect_mul_frac(SIZE_MAX, "1.0", SIZE_MAX); 260*7bdf38e5Schristos expect_mul_frac(SIZE_MAX, ".75", SIZE_MAX / 4 * 3); 261*7bdf38e5Schristos expect_mul_frac(SIZE_MAX, ".5", SIZE_MAX / 2); 262*7bdf38e5Schristos expect_mul_frac(SIZE_MAX, ".25", SIZE_MAX / 4); 263*7bdf38e5Schristos expect_mul_frac(1U << 16, "1.0", 1U << 16); 264*7bdf38e5Schristos expect_mul_frac(1U << 30, "0.5", 1U << 29); 265*7bdf38e5Schristos expect_mul_frac(1U << 30, "0.25", 1U << 28); 266*7bdf38e5Schristos expect_mul_frac(1U << 30, "0.125", 1U << 27); 267*7bdf38e5Schristos expect_mul_frac((1U << 30) + 1, "0.125", 1U << 27); 268*7bdf38e5Schristos expect_mul_frac(100, "0.25", 25); 269*7bdf38e5Schristos expect_mul_frac(1000 * 1000, "0.001", 1000); 270*7bdf38e5Schristos } 271*7bdf38e5Schristos TEST_END 272*7bdf38e5Schristos 273*7bdf38e5Schristos static void 274*7bdf38e5Schristos expect_print(const char *str) { 275*7bdf38e5Schristos fxp_t fxp = xparse_fxp(str); 276*7bdf38e5Schristos char buf[FXP_BUF_SIZE]; 277*7bdf38e5Schristos fxp_print(fxp, buf); 278*7bdf38e5Schristos expect_d_eq(0, strcmp(str, buf), "Couldn't round-trip print %s", str); 279*7bdf38e5Schristos } 280*7bdf38e5Schristos 281*7bdf38e5Schristos TEST_BEGIN(test_print_simple) { 282*7bdf38e5Schristos expect_print("0.0"); 283*7bdf38e5Schristos expect_print("1.0"); 284*7bdf38e5Schristos expect_print("2.0"); 285*7bdf38e5Schristos expect_print("123.0"); 286*7bdf38e5Schristos /* 287*7bdf38e5Schristos * We hit the possibility of roundoff errors whenever the fractional 288*7bdf38e5Schristos * component isn't a round binary number; only check these here (we 289*7bdf38e5Schristos * round-trip properly in the stress test). 290*7bdf38e5Schristos */ 291*7bdf38e5Schristos expect_print("1.5"); 292*7bdf38e5Schristos expect_print("3.375"); 293*7bdf38e5Schristos expect_print("0.25"); 294*7bdf38e5Schristos expect_print("0.125"); 295*7bdf38e5Schristos /* 1 / 2**14 */ 296*7bdf38e5Schristos expect_print("0.00006103515625"); 297*7bdf38e5Schristos } 298*7bdf38e5Schristos TEST_END 299*7bdf38e5Schristos 300*7bdf38e5Schristos TEST_BEGIN(test_stress) { 301*7bdf38e5Schristos const char *numbers[] = { 302*7bdf38e5Schristos "0.0", "0.1", "0.2", "0.3", "0.4", 303*7bdf38e5Schristos "0.5", "0.6", "0.7", "0.8", "0.9", 304*7bdf38e5Schristos 305*7bdf38e5Schristos "1.0", "1.1", "1.2", "1.3", "1.4", 306*7bdf38e5Schristos "1.5", "1.6", "1.7", "1.8", "1.9", 307*7bdf38e5Schristos 308*7bdf38e5Schristos "2.0", "2.1", "2.2", "2.3", "2.4", 309*7bdf38e5Schristos "2.5", "2.6", "2.7", "2.8", "2.9", 310*7bdf38e5Schristos 311*7bdf38e5Schristos "17.0", "17.1", "17.2", "17.3", "17.4", 312*7bdf38e5Schristos "17.5", "17.6", "17.7", "17.8", "17.9", 313*7bdf38e5Schristos 314*7bdf38e5Schristos "18.0", "18.1", "18.2", "18.3", "18.4", 315*7bdf38e5Schristos "18.5", "18.6", "18.7", "18.8", "18.9", 316*7bdf38e5Schristos 317*7bdf38e5Schristos "123.0", "123.1", "123.2", "123.3", "123.4", 318*7bdf38e5Schristos "123.5", "123.6", "123.7", "123.8", "123.9", 319*7bdf38e5Schristos 320*7bdf38e5Schristos "124.0", "124.1", "124.2", "124.3", "124.4", 321*7bdf38e5Schristos "124.5", "124.6", "124.7", "124.8", "124.9", 322*7bdf38e5Schristos 323*7bdf38e5Schristos "125.0", "125.1", "125.2", "125.3", "125.4", 324*7bdf38e5Schristos "125.5", "125.6", "125.7", "125.8", "125.9"}; 325*7bdf38e5Schristos size_t numbers_len = sizeof(numbers)/sizeof(numbers[0]); 326*7bdf38e5Schristos for (size_t i = 0; i < numbers_len; i++) { 327*7bdf38e5Schristos fxp_t fxp_a = xparse_fxp(numbers[i]); 328*7bdf38e5Schristos double double_a = strtod(numbers[i], NULL); 329*7bdf38e5Schristos 330*7bdf38e5Schristos uint32_t fxp_rounded_down = fxp_round_down(fxp_a); 331*7bdf38e5Schristos uint32_t fxp_rounded_nearest = fxp_round_nearest(fxp_a); 332*7bdf38e5Schristos uint32_t double_rounded_down = (uint32_t)double_a; 333*7bdf38e5Schristos uint32_t double_rounded_nearest = (uint32_t)round(double_a); 334*7bdf38e5Schristos 335*7bdf38e5Schristos expect_u32_eq(double_rounded_down, fxp_rounded_down, 336*7bdf38e5Schristos "Incorrectly rounded down %s", numbers[i]); 337*7bdf38e5Schristos expect_u32_eq(double_rounded_nearest, fxp_rounded_nearest, 338*7bdf38e5Schristos "Incorrectly rounded-to-nearest %s", numbers[i]); 339*7bdf38e5Schristos 340*7bdf38e5Schristos for (size_t j = 0; j < numbers_len; j++) { 341*7bdf38e5Schristos fxp_t fxp_b = xparse_fxp(numbers[j]); 342*7bdf38e5Schristos double double_b = strtod(numbers[j], NULL); 343*7bdf38e5Schristos 344*7bdf38e5Schristos fxp_t fxp_sum = fxp_add(fxp_a, fxp_b); 345*7bdf38e5Schristos double double_sum = double_a + double_b; 346*7bdf38e5Schristos expect_true( 347*7bdf38e5Schristos double_close(fxp2double(fxp_sum), double_sum), 348*7bdf38e5Schristos "Miscomputed %s + %s", numbers[i], numbers[j]); 349*7bdf38e5Schristos 350*7bdf38e5Schristos if (double_a > double_b) { 351*7bdf38e5Schristos fxp_t fxp_diff = fxp_sub(fxp_a, fxp_b); 352*7bdf38e5Schristos double double_diff = double_a - double_b; 353*7bdf38e5Schristos expect_true( 354*7bdf38e5Schristos double_close(fxp2double(fxp_diff), 355*7bdf38e5Schristos double_diff), 356*7bdf38e5Schristos "Miscomputed %s - %s", numbers[i], 357*7bdf38e5Schristos numbers[j]); 358*7bdf38e5Schristos } 359*7bdf38e5Schristos 360*7bdf38e5Schristos fxp_t fxp_prod = fxp_mul(fxp_a, fxp_b); 361*7bdf38e5Schristos double double_prod = double_a * double_b; 362*7bdf38e5Schristos expect_true( 363*7bdf38e5Schristos double_close(fxp2double(fxp_prod), double_prod), 364*7bdf38e5Schristos "Miscomputed %s * %s", numbers[i], numbers[j]); 365*7bdf38e5Schristos 366*7bdf38e5Schristos if (double_b != 0.0) { 367*7bdf38e5Schristos fxp_t fxp_quot = fxp_div(fxp_a, fxp_b); 368*7bdf38e5Schristos double double_quot = double_a / double_b; 369*7bdf38e5Schristos expect_true( 370*7bdf38e5Schristos double_close(fxp2double(fxp_quot), 371*7bdf38e5Schristos double_quot), 372*7bdf38e5Schristos "Miscomputed %s / %s", numbers[i], 373*7bdf38e5Schristos numbers[j]); 374*7bdf38e5Schristos } 375*7bdf38e5Schristos } 376*7bdf38e5Schristos } 377*7bdf38e5Schristos } 378*7bdf38e5Schristos TEST_END 379*7bdf38e5Schristos 380*7bdf38e5Schristos int 381*7bdf38e5Schristos main(void) { 382*7bdf38e5Schristos return test_no_reentrancy( 383*7bdf38e5Schristos test_parse_valid, 384*7bdf38e5Schristos test_parse_invalid, 385*7bdf38e5Schristos test_init_percent, 386*7bdf38e5Schristos test_add_simple, 387*7bdf38e5Schristos test_sub_simple, 388*7bdf38e5Schristos test_mul_simple, 389*7bdf38e5Schristos test_div_simple, 390*7bdf38e5Schristos test_round_simple, 391*7bdf38e5Schristos test_mul_frac_simple, 392*7bdf38e5Schristos test_print_simple, 393*7bdf38e5Schristos test_stress); 394*7bdf38e5Schristos } 395