Skip to content

Commit 0de3e89

Browse files
committed
degrees and rad2deg impl
1 parent 0f1e4a6 commit 0de3e89

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

quaddtype/numpy_quaddtype/src/ops.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,15 @@ quad_atanh(const Sleef_quad *op)
243243
return Sleef_atanhq1_u10(*op);
244244
}
245245

246+
static inline Sleef_quad
247+
quad_degrees(const Sleef_quad *op)
248+
{
249+
// degrees = radians * 180 / π
250+
static const Sleef_quad one_eighty = Sleef_strtoq("180.0", NULL);
251+
Sleef_quad ratio = Sleef_divq1_u05(one_eighty, SLEEF_M_PIq);
252+
return Sleef_mulq1_u05(*op, ratio);
253+
}
254+
246255
// Unary long double operations
247256
typedef long double (*unary_op_longdouble_def)(const long double *);
248257

@@ -446,6 +455,16 @@ ld_atanh(const long double *op)
446455
return atanhl(*op);
447456
}
448457

458+
static inline long double
459+
ld_degrees(const long double *op)
460+
{
461+
// degrees = radians * 180 / π
462+
#ifndef M_PI
463+
#define M_PI 3.14159265358979323846
464+
#endif
465+
return (*op) * (180.0L / static_cast<long double>(M_PI));
466+
}
467+
449468
// Unary Quad properties
450469
typedef npy_bool (*unary_prop_quad_def)(const Sleef_quad *);
451470

quaddtype/numpy_quaddtype/src/umath/unary_ops.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,5 +250,11 @@ init_quad_unary_ops(PyObject *numpy)
250250
if (create_quad_unary_ufunc<quad_atanh, ld_atanh>(numpy, "arctanh") < 0) {
251251
return -1;
252252
}
253+
if (create_quad_unary_ufunc<quad_degrees, ld_degrees>(numpy, "degrees") < 0) {
254+
return -1;
255+
}
256+
if (create_quad_unary_ufunc<quad_degrees, ld_degrees>(numpy, "rad2deg") < 0) {
257+
return -1;
258+
}
253259
return 0;
254260
}

quaddtype/release_tracker.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@
5454
| arcsinh |||
5555
| arccosh |||
5656
| arctanh |||
57-
| degrees | | |
57+
| degrees | | |
5858
| radians | | |
5959
| deg2rad | | |
60-
| rad2deg | | |
60+
| rad2deg | | |
6161
| bitwise_and | | |
6262
| bitwise_or | | |
6363
| bitwise_xor | | |

quaddtype/tests/test_quaddtype.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,3 +1905,44 @@ def test_hypot(x1, x2, expected):
19051905
else:
19061906
np.testing.assert_allclose(float(result), expected, rtol=1e-13)
19071907

1908+
1909+
@pytest.mark.parametrize("op", [np.degrees, np.rad2deg])
1910+
@pytest.mark.parametrize("radians,expected_degrees", [
1911+
# Basic conversions
1912+
(0.0, 0.0),
1913+
(np.pi / 6, 30.0),
1914+
(np.pi / 4, 45.0),
1915+
(np.pi / 3, 60.0),
1916+
(np.pi / 2, 90.0),
1917+
(np.pi, 180.0),
1918+
(3 * np.pi / 2, 270.0),
1919+
(2 * np.pi, 360.0),
1920+
# Negative values
1921+
(-np.pi / 2, -90.0),
1922+
(-np.pi, -180.0),
1923+
# Special values
1924+
(np.inf, np.inf),
1925+
(-np.inf, -np.inf),
1926+
(np.nan, np.nan),
1927+
# Edge cases
1928+
(0.0, 0.0),
1929+
(-0.0, -0.0),
1930+
])
1931+
def test_degrees_rad2deg(op, radians, expected_degrees):
1932+
"""Test degrees and rad2deg ufuncs convert radians to degrees"""
1933+
q_rad = QuadPrecision(radians)
1934+
result = op(q_rad)
1935+
1936+
assert isinstance(result, QuadPrecision)
1937+
1938+
if np.isnan(expected_degrees):
1939+
assert np.isnan(float(result))
1940+
elif np.isinf(expected_degrees):
1941+
assert np.isinf(float(result))
1942+
if expected_degrees > 0:
1943+
assert float(result) > 0
1944+
else:
1945+
assert float(result) < 0
1946+
else:
1947+
np.testing.assert_allclose(float(result), expected_degrees, rtol=1e-13)
1948+

0 commit comments

Comments
 (0)