Skip to content

Commit 3216c13

Browse files
Test and fix 0^-x
Fix #995
1 parent bc29d96 commit 3216c13

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

include/xsimd/arch/generic/xsimd_generic_math.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,14 +1942,13 @@ namespace xsimd
19421942
{
19431943
using batch_type = batch<T, A>;
19441944
const auto zero = batch_type(0.);
1945-
auto negx = self < zero;
1946-
auto iszero = self == zero;
1947-
constexpr T e = static_cast<T>(2.718281828459045);
1948-
auto adj_self = select(iszero, batch_type(e), abs(self));
1945+
auto negself = self < zero;
1946+
auto iszeropowpos = self == zero && other >= zero;
1947+
auto adj_self = select(iszeropowpos, batch_type(1), abs(self));
19491948
batch_type z = exp(other * log(adj_self));
1950-
z = select(iszero, zero, z);
1951-
z = select(is_odd(other) && negx, -z, z);
1952-
auto invalid = negx && !(is_flint(other) || isinf(other));
1949+
z = select(iszeropowpos, zero, z);
1950+
z = select(is_odd(other) && negself, -z, z);
1951+
auto invalid = negself && !(is_flint(other) || isinf(other));
19531952
return select(invalid, constants::nan<batch_type>(), z);
19541953
}
19551954

test/test_power.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct power_test
2323
using vector_type = std::vector<value_type>;
2424

2525
size_t nb_input;
26+
vector_type zero_input;
2627
vector_type zlhs_input;
2728
vector_type lhs_input;
2829
vector_type rhs_input;
@@ -32,11 +33,13 @@ struct power_test
3233
power_test()
3334
{
3435
nb_input = size * 10000;
36+
zero_input.resize(nb_input);
3537
zlhs_input.resize(nb_input);
3638
lhs_input.resize(nb_input);
3739
rhs_input.resize(nb_input);
3840
for (size_t i = 0; i < nb_input; ++i)
3941
{
42+
zero_input[i] = 0;
4043
lhs_input[i] = value_type(i) / 4 + value_type(1.2) * std::sqrt(value_type(i + 0.25));
4144
zlhs_input[i] = lhs_input[i] * (i % 2);
4245
rhs_input[i] = value_type(10.2) / (i + 2) + value_type(0.25);
@@ -79,7 +82,7 @@ struct power_test
7982
detail::store_batch(out, res, i);
8083
}
8184
size_t diff = detail::get_nb_diff(res, expected);
82-
INFO("pow");
85+
INFO("0 ^ x");
8386
CHECK_EQ(diff, 0);
8487

8588
// use of undeclared identifier '_MM_SET_EXCEPTION_MASK for emscripten
@@ -96,10 +99,27 @@ struct power_test
9699
}
97100
_MM_SET_EXCEPTION_MASK(mask);
98101
diff = detail::get_nb_diff(res, expected);
99-
INFO("pow");
102+
INFO("0 ^ x with exception");
100103
CHECK_EQ(diff, 0);
101104
#endif
102105
}
106+
// pow 0^-x
107+
{
108+
std::transform(zero_input.cbegin(), zero_input.cend(), rhs_input.cbegin(), expected.begin(),
109+
[](const value_type& z, const value_type& r)
110+
{ return std::pow(z, -r); });
111+
batch_type zero_in, rhs_in, out;
112+
for (size_t i = 0; i < nb_input; i += size)
113+
{
114+
detail::load_batch(zero_in, zero_input, i);
115+
detail::load_batch(rhs_in, rhs_input, i);
116+
out = pow(zero_in, -rhs_in);
117+
detail::store_batch(out, res, i);
118+
}
119+
size_t diff = detail::get_nb_diff(res, expected);
120+
INFO("pow(0, -x)");
121+
CHECK_EQ(diff, 0);
122+
}
103123
// ipow
104124
{
105125
long k = 0;

0 commit comments

Comments
 (0)