add random y^x tests
This commit is contained in:
parent
d3cddc1326
commit
540d9e282c
@ -732,6 +732,52 @@ TEST_CASE("exp large random"){
|
|||||||
test_exp_random(1);
|
test_exp_random(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pow_test(){ // a^b
|
||||||
|
bmp::mpf_float::default_precision(50);
|
||||||
|
decn_to_str_complete(&AccDecn);
|
||||||
|
CAPTURE(Buf); // a
|
||||||
|
bmp::mpfr_float a_actual(Buf);
|
||||||
|
decn_to_str_complete(&BDecn);
|
||||||
|
CAPTURE(Buf); // b
|
||||||
|
bmp::mpfr_float b_actual(Buf);
|
||||||
|
//calculate result
|
||||||
|
pow_decn();
|
||||||
|
//calculate actual result
|
||||||
|
bmp::mpfr_float res_actual(pow(a_actual, b_actual));
|
||||||
|
//check overflow or underflow
|
||||||
|
if (decn_is_nan(&AccDecn)){
|
||||||
|
//check overflow or underflow
|
||||||
|
if (b_actual > 0) {
|
||||||
|
CHECK(log(res_actual) > 100);
|
||||||
|
} else {
|
||||||
|
CHECK(log(res_actual) < -100);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//not over/underflow, get string and log calculated result
|
||||||
|
decn_to_str_complete(&AccDecn);
|
||||||
|
CAPTURE(Buf); // a^b
|
||||||
|
bmp::mpfr_float calculated(Buf);
|
||||||
|
//check relative error
|
||||||
|
double rel_tol = 4.5e-14;
|
||||||
|
if (a_actual > 1.0 && a_actual < 1.0001){
|
||||||
|
rel_tol = 1e-7;
|
||||||
|
} else if (a_actual > 0.9 && a_actual < 2.0){
|
||||||
|
rel_tol = 1.5e-10;
|
||||||
|
} else if (log(res_actual) > 100){
|
||||||
|
rel_tol = 1e-12;
|
||||||
|
}
|
||||||
|
CAPTURE(a_actual);
|
||||||
|
CAPTURE(rel_tol);
|
||||||
|
if (decn_is_zero(&AccDecn)) {
|
||||||
|
bmp::mpfr_float diff = abs(res_actual - calculated);
|
||||||
|
CHECK(diff < rel_tol);
|
||||||
|
} else {
|
||||||
|
bmp::mpfr_float rel_diff = abs((res_actual - calculated)/res_actual);
|
||||||
|
CHECK(rel_diff < rel_tol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void pow_test(
|
static void pow_test(
|
||||||
//input
|
//input
|
||||||
const char* a_str, int a_exp,
|
const char* a_str, int a_exp,
|
||||||
@ -744,31 +790,7 @@ static void pow_test(
|
|||||||
//compute power
|
//compute power
|
||||||
build_decn_at(&BDecn, b_str, b_exp);
|
build_decn_at(&BDecn, b_str, b_exp);
|
||||||
build_dec80(a_str, a_exp);
|
build_dec80(a_str, a_exp);
|
||||||
|
pow_test();
|
||||||
pow_decn();
|
|
||||||
|
|
||||||
decn_to_str_complete(&AccDecn);
|
|
||||||
CAPTURE(Buf); // a^b
|
|
||||||
|
|
||||||
//calculate actual result
|
|
||||||
bmp::mpfr_float::default_precision(50);
|
|
||||||
bmp::mpfr_float calculated(Buf);
|
|
||||||
std::string a_full_str(a_str);
|
|
||||||
a_full_str += "e" + std::to_string(a_exp);
|
|
||||||
std::string b_full_str(b_str);
|
|
||||||
b_full_str += "e" + std::to_string(b_exp);;
|
|
||||||
// CAPTURE(a_full_str);
|
|
||||||
// CAPTURE(b_full_str);
|
|
||||||
bmp::mpfr_float a_actual(a_full_str);
|
|
||||||
bmp::mpfr_float b_actual(b_full_str);
|
|
||||||
a_actual = pow(a_actual, b_actual);
|
|
||||||
if (decn_is_zero(&AccDecn)) {
|
|
||||||
bmp::mpfr_float diff = abs(a_actual - calculated);
|
|
||||||
CHECK(diff < 3e-14);
|
|
||||||
} else {
|
|
||||||
bmp::mpfr_float rel_diff = abs((a_actual - calculated)/a_actual);
|
|
||||||
CHECK(rel_diff < 3e-14);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("power"){
|
TEST_CASE("power"){
|
||||||
@ -803,6 +825,58 @@ TEST_CASE("power"){
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void power_test(int lsu0_low, int lsu0_high, int exp_low=-99, int exp_high=99){
|
||||||
|
std::default_random_engine gen;
|
||||||
|
std::uniform_int_distribution<int> lsu0_distrib(lsu0_low, lsu0_high);
|
||||||
|
std::uniform_int_distribution<int> distrib(0, 99);
|
||||||
|
std::uniform_int_distribution<int> exp_distrib(exp_low, exp_high);
|
||||||
|
std::uniform_int_distribution<int> sign_distrib(0,1);
|
||||||
|
for (int j = 0; j < NUM_RAND_TESTS; j++){
|
||||||
|
AccDecn.lsu[0] = lsu0_distrib(gen);
|
||||||
|
for (int i = 1; i < DEC80_NUM_LSU; i++){
|
||||||
|
AccDecn.lsu[i] = distrib(gen);
|
||||||
|
BDecn.lsu[i] = distrib(gen);
|
||||||
|
}
|
||||||
|
set_exponent(&AccDecn, exp_distrib(gen), 0);
|
||||||
|
//generate exponent for b to minimize chance of a^b overflowing:
|
||||||
|
// a^b <= 1e100
|
||||||
|
// b*log(a) <= log(1e100) = 100
|
||||||
|
// b <= 100/log(a)
|
||||||
|
// b_exponent <= log(100/log(a)) = log(100) - log(log(a))
|
||||||
|
// b_exponent <= 2 - log(log(a))
|
||||||
|
decn_to_str_complete(&AccDecn);
|
||||||
|
bmp::mpfr_float acc(Buf);
|
||||||
|
acc = 2.0 - log(log(acc));
|
||||||
|
double b_exponent_high_flt = acc.convert_to<double>();
|
||||||
|
int b_exponent_high = b_exponent_high_flt;
|
||||||
|
int b_exponent_low = -99;
|
||||||
|
//ensure b_exponent high in range
|
||||||
|
if (b_exponent_high > 99){
|
||||||
|
b_exponent_high = 99;
|
||||||
|
} else if (b_exponent_high < b_exponent_low){
|
||||||
|
b_exponent_high = b_exponent_low;
|
||||||
|
}
|
||||||
|
CAPTURE(b_exponent_low);
|
||||||
|
CAPTURE(b_exponent_high);
|
||||||
|
std::uniform_int_distribution<int> b_exp_distrib(b_exponent_low, b_exponent_high);
|
||||||
|
int b_exponent = b_exp_distrib(gen);
|
||||||
|
CAPTURE(b_exponent);
|
||||||
|
int b_neg = sign_distrib(gen);
|
||||||
|
set_exponent(&BDecn, b_exponent, b_neg);
|
||||||
|
pow_test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("power random"){
|
||||||
|
power_test(0, 99);
|
||||||
|
}
|
||||||
|
TEST_CASE("power random 0.9 to 0.99..."){
|
||||||
|
power_test(90, 99, -1, -1);
|
||||||
|
}
|
||||||
|
TEST_CASE("power random 1.0 to 2.0..."){
|
||||||
|
power_test(10, 20, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("u32str corner"){
|
TEST_CASE("u32str corner"){
|
||||||
u32str(0, &Buf[0], 10);
|
u32str(0, &Buf[0], 10);
|
||||||
CHECK_THAT(Buf, Equals("0"));
|
CHECK_THAT(Buf, Equals("0"));
|
||||||
|
Loading…
Reference in New Issue
Block a user