Skip to content

Commit c8175c8

Browse files
committed
to_quad + sign tests
1 parent efc51e9 commit c8175c8

2 files changed

Lines changed: 63 additions & 9 deletions

File tree

quaddtype/numpy_quaddtype/src/casts.cpp

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -950,11 +950,21 @@ inline quad_value
950950
to_quad<spec_npy_half>(npy_half x, QuadBackendType backend)
951951
{
952952
quad_value result;
953+
double d = npy_half_to_double(x);
953954
if (backend == BACKEND_SLEEF) {
954-
result.sleef_value = Sleef_cast_from_doubleq1(npy_half_to_double(x));
955+
if (std::isnan(d)) {
956+
result.sleef_value = std::signbit(d) ? QUAD_PRECISION_NEG_NAN : QUAD_PRECISION_NAN;
957+
}
958+
else if (std::isinf(d)) {
959+
result.sleef_value = (d > 0) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF;
960+
}
961+
else {
962+
Sleef_quad temp = Sleef_cast_from_doubleq1(d);
963+
std::memcpy(&result.sleef_value, &temp, sizeof(Sleef_quad));
964+
}
955965
}
956966
else {
957-
result.longdouble_value = (long double)npy_half_to_double(x);
967+
result.longdouble_value = (long double)d;
958968
}
959969
return result;
960970
}
@@ -964,8 +974,18 @@ inline quad_value
964974
to_quad<float>(float x, QuadBackendType backend)
965975
{
966976
quad_value result;
967-
if (backend == BACKEND_SLEEF) {
968-
result.sleef_value = Sleef_cast_from_doubleq1(x);
977+
if (backend == BACKEND_SLEEF)
978+
{
979+
if (std::isnan(x)) {
980+
result.sleef_value = std::signbit(x) ? QUAD_PRECISION_NEG_NAN : QUAD_PRECISION_NAN;
981+
}
982+
else if (std::isinf(x)) {
983+
result.sleef_value = (x > 0) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF;
984+
}
985+
else {
986+
Sleef_quad temp = Sleef_cast_from_doubleq1(static_cast<double>(x));
987+
std::memcpy(&result.sleef_value, &temp, sizeof(Sleef_quad));
988+
}
969989
}
970990
else {
971991
result.longdouble_value = (long double)x;
@@ -978,8 +998,18 @@ inline quad_value
978998
to_quad<double>(double x, QuadBackendType backend)
979999
{
9801000
quad_value result;
981-
if (backend == BACKEND_SLEEF) {
982-
result.sleef_value = Sleef_cast_from_doubleq1(x);
1001+
if (backend == BACKEND_SLEEF)
1002+
{
1003+
if (std::isnan(x)) {
1004+
result.sleef_value = std::signbit(x) ? QUAD_PRECISION_NEG_NAN : QUAD_PRECISION_NAN;
1005+
}
1006+
else if (std::isinf(x)) {
1007+
result.sleef_value = (x > 0) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF;
1008+
}
1009+
else {
1010+
Sleef_quad temp = Sleef_cast_from_doubleq1(x);
1011+
std::memcpy(&result.sleef_value, &temp, sizeof(Sleef_quad));
1012+
}
9831013
}
9841014
else {
9851015
result.longdouble_value = (long double)x;
@@ -992,8 +1022,18 @@ inline quad_value
9921022
to_quad<long double>(long double x, QuadBackendType backend)
9931023
{
9941024
quad_value result;
995-
if (backend == BACKEND_SLEEF) {
996-
result.sleef_value = Sleef_cast_from_doubleq1(x);
1025+
if (backend == BACKEND_SLEEF)
1026+
{
1027+
if (std::isnan(x)) {
1028+
result.sleef_value = std::signbit(x) ? QUAD_PRECISION_NEG_NAN : QUAD_PRECISION_NAN;
1029+
}
1030+
else if (std::isinf(x)) {
1031+
result.sleef_value = (x > 0) ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF;
1032+
}
1033+
else {
1034+
Sleef_quad temp = Sleef_cast_from_doubleq1(static_cast<double>(x));
1035+
std::memcpy(&result.sleef_value, &temp, sizeof(Sleef_quad));
1036+
}
9971037
}
9981038
else {
9991039
result.longdouble_value = x;

quaddtype/tests/test_quaddtype.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5397,4 +5397,18 @@ def test_quad_to_quad_backend_casting(src_backend, dst_backend, value):
53975397
elif src_backend != dst_backend:
53985398
np.testing.assert_allclose(dst_arr, res_arr, rtol=1e-15)
53995399
else:
5400-
np.testing.assert_array_equal(dst_arr, res_arr)
5400+
np.testing.assert_array_equal(dst_arr, res_arr)
5401+
5402+
# quad -> float will be tested in same_values tests
5403+
@pytest.mark.parametrize("dtype", [np.float16, np.float32, np.float64, np.longdouble])
5404+
@pytest.mark.parametrize("val", [0.0, -0.0, float('inf'), float('-inf'), float('nan'), float("-nan")])
5405+
def test_float_to_quad_sign_preserve(dtype, val):
5406+
"""Test that special floating-point values roundtrip correctly."""
5407+
src = np.array([val], dtype=dtype)
5408+
result = src.astype(QuadPrecDType())
5409+
5410+
assert np.signbit(result) == np.signbit(val), f"Sign bit failed for {dtype} with value {val}"
5411+
if np.isnan(val):
5412+
assert np.isnan(result), f"NaN failed for {dtype}"
5413+
else:
5414+
assert result == val, f"{val} failed for {dtype}"

0 commit comments

Comments
 (0)