Skip to content

Commit adf0bc4

Browse files
committed
improve signbit assert
1 parent 4bca201 commit adf0bc4

2 files changed

Lines changed: 16 additions & 22 deletions

File tree

quaddtype/numpy_quaddtype/src/ops.hpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
#include <cmath>
44
#include "constants.hpp"
55

6-
// Quad Constants, generated with qutil
7-
#define QUAD_ONE sleef_q(+0x1000000000000LL, 0x0000000000000000ULL, 0)
8-
96
// Unary Quad Operations
107
typedef Sleef_quad (*unary_op_quad_def)(const Sleef_quad *);
118
// Unary Quad operations with 2 outputs (for modf, frexp)
@@ -104,7 +101,7 @@ quad_cbrt(const Sleef_quad *op)
104101

105102
// Compute 1/3 as a quad precision constant
106103
Sleef_quad three = Sleef_cast_from_int64q1(3);
107-
Sleef_quad one_third = Sleef_divq1_u05(QUAD_ONE, three);
104+
Sleef_quad one_third = Sleef_divq1_u05(QUAD_PRECISION_ONE, three);
108105

109106
// Handle negative values: cbrt(-x) = -cbrt(x)
110107
if (Sleef_icmpltq1(*op, QUAD_PRECISION_ZERO)) {
@@ -126,7 +123,7 @@ quad_square(const Sleef_quad *op)
126123
static inline Sleef_quad
127124
quad_reciprocal(const Sleef_quad *op)
128125
{
129-
return Sleef_divq1_u05(QUAD_ONE, *op);
126+
return Sleef_divq1_u05(QUAD_PRECISION_ONE, *op);
130127
}
131128

132129
static inline Sleef_quad
@@ -492,7 +489,7 @@ quad_signbit(const Sleef_quad *op)
492489
{
493490
// FIXME @juntyr or @SwayamInSync: replace with binary implementation
494491
// once we test big and little endian in CI
495-
Sleef_quad one_signed = Sleef_copysignq1(QUAD_ONE, *op);
492+
Sleef_quad one_signed = Sleef_copysignq1(QUAD_PRECISION_ONE, *op);
496493
// signbit(x) = 1 iff copysign(1, x) == -1
497494
return Sleef_icmpltq1(one_signed, QUAD_PRECISION_ZERO);
498495
}
@@ -600,7 +597,7 @@ quad_floor_divide(const Sleef_quad *a, const Sleef_quad *b)
600597
// But NOT when numerator is ±0.0 (then result stays as ±0.0)
601598
if (Sleef_icmpeqq1(result, QUAD_PRECISION_ZERO) && quad_signbit(&result) &&
602599
!Sleef_icmpeqq1(*a, QUAD_PRECISION_ZERO)) {
603-
return Sleef_negq1(QUAD_ONE); // -1.0
600+
return Sleef_negq1(QUAD_PRECISION_ONE); // -1.0
604601
}
605602

606603
return result;
@@ -687,7 +684,7 @@ quad_fmod(const Sleef_quad *a, const Sleef_quad *b)
687684

688685
if (Sleef_icmpeqq1(result, QUAD_PRECISION_ZERO)) {
689686
// Preserve sign of dividend (first argument)
690-
Sleef_quad sign_test = Sleef_copysignq1(QUAD_ONE, *a);
687+
Sleef_quad sign_test = Sleef_copysignq1(QUAD_PRECISION_ONE, *a);
691688
if (Sleef_icmpltq1(sign_test, QUAD_PRECISION_ZERO)) {
692689
return Sleef_negq1(QUAD_PRECISION_ZERO); // -0.0
693690
}
@@ -715,7 +712,7 @@ quad_minimum(const Sleef_quad *in1, const Sleef_quad *in2)
715712
}
716713
// minimum(-0.0, +0.0) = -0.0
717714
if (Sleef_icmpeqq1(*in1, QUAD_PRECISION_ZERO) && Sleef_icmpeqq1(*in2, QUAD_PRECISION_ZERO)) {
718-
return Sleef_icmpleq1(Sleef_copysignq1(QUAD_ONE, *in1), Sleef_copysignq1(QUAD_ONE, *in2)) ? *in1 : *in2;
715+
return Sleef_icmpleq1(Sleef_copysignq1(QUAD_PRECISION_ONE, *in1), Sleef_copysignq1(QUAD_PRECISION_ONE, *in2)) ? *in1 : *in2;
719716
}
720717
return Sleef_fminq1(*in1, *in2);
721718
}
@@ -728,7 +725,7 @@ quad_maximum(const Sleef_quad *in1, const Sleef_quad *in2)
728725
}
729726
// maximum(-0.0, +0.0) = +0.0
730727
if (Sleef_icmpeqq1(*in1, QUAD_PRECISION_ZERO) && Sleef_icmpeqq1(*in2, QUAD_PRECISION_ZERO)) {
731-
return Sleef_icmpgeq1(Sleef_copysignq1(QUAD_ONE, *in1), Sleef_copysignq1(QUAD_ONE, *in2)) ? *in1 : *in2;
728+
return Sleef_icmpgeq1(Sleef_copysignq1(QUAD_PRECISION_ONE, *in1), Sleef_copysignq1(QUAD_PRECISION_ONE, *in2)) ? *in1 : *in2;
732729
}
733730
return Sleef_fmaxq1(*in1, *in2);
734731
}
@@ -741,7 +738,7 @@ quad_fmin(const Sleef_quad *in1, const Sleef_quad *in2)
741738
}
742739
// fmin(-0.0, +0.0) = -0.0
743740
if (Sleef_icmpeqq1(*in1, QUAD_PRECISION_ZERO) && Sleef_icmpeqq1(*in2, QUAD_PRECISION_ZERO)) {
744-
return Sleef_icmpleq1(Sleef_copysignq1(QUAD_ONE, *in1), Sleef_copysignq1(QUAD_ONE, *in2)) ? *in1 : *in2;
741+
return Sleef_icmpleq1(Sleef_copysignq1(QUAD_PRECISION_ONE, *in1), Sleef_copysignq1(QUAD_PRECISION_ONE, *in2)) ? *in1 : *in2;
745742
}
746743
return Sleef_fminq1(*in1, *in2);
747744
}
@@ -754,7 +751,7 @@ quad_fmax(const Sleef_quad *in1, const Sleef_quad *in2)
754751
}
755752
// maximum(-0.0, +0.0) = +0.0
756753
if (Sleef_icmpeqq1(*in1, QUAD_PRECISION_ZERO) && Sleef_icmpeqq1(*in2, QUAD_PRECISION_ZERO)) {
757-
return Sleef_icmpgeq1(Sleef_copysignq1(QUAD_ONE, *in1), Sleef_copysignq1(QUAD_ONE, *in2)) ? *in1 : *in2;
754+
return Sleef_icmpgeq1(Sleef_copysignq1(QUAD_PRECISION_ONE, *in1), Sleef_copysignq1(QUAD_PRECISION_ONE, *in2)) ? *in1 : *in2;
758755
}
759756
return Sleef_fmaxq1(*in1, *in2);
760757
}
@@ -849,7 +846,7 @@ quad_logaddexp2(const Sleef_quad *x, const Sleef_quad *y)
849846
Sleef_quad abs_diff = Sleef_fabsq1(diff);
850847
Sleef_quad neg_abs_diff = Sleef_negq1(abs_diff);
851848
Sleef_quad exp2_term = Sleef_exp2q1_u10(neg_abs_diff);
852-
Sleef_quad one_plus_exp2 = Sleef_addq1_u05(QUAD_ONE, exp2_term);
849+
Sleef_quad one_plus_exp2 = Sleef_addq1_u05(QUAD_PRECISION_ONE, exp2_term);
853850
Sleef_quad log2_term = Sleef_log2q1_u10(one_plus_exp2);
854851

855852
Sleef_quad max_val = Sleef_icmpgtq1(*x, *y) ? *x : *y;
@@ -872,7 +869,7 @@ quad_heaviside(const Sleef_quad *x1, const Sleef_quad *x2)
872869
return *x2; // When x1 == 0, return x2 (even if x2 is NaN)
873870
}
874871
else {
875-
return QUAD_ONE;
872+
return QUAD_PRECISION_ONE;
876873
}
877874
}
878875

quaddtype/tests/test_quaddtype.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5459,8 +5459,8 @@ def test_same_value_cast_floats_special_values(self, dtype, val):
54595459
"""Test that special floating-point values roundtrip correctly."""
54605460
q = np.array([val], dtype=QuadPrecDType())
54615461
result = q.astype(dtype, casting="same_value")
5462-
if str(val).startswith("-"):
5463-
assert np.signbit(result), f"Sign bit failed for {dtype} with value {val}"
5462+
5463+
assert np.signbit(result) == np.signbit(val), f"Sign bit failed for {dtype} with value {val}"
54645464
if np.isnan(val):
54655465
assert np.isnan(result), f"NaN failed for {dtype}"
54665466
else:
@@ -5550,8 +5550,7 @@ def test_same_value_cast_strings_enough_width(self, dtype):
55505550
result = q.astype(dtype, casting="same_value")
55515551
# Convert back and verify
55525552
back = result.astype(QuadPrecDType())
5553-
if str(val).startswith("-"):
5554-
assert np.signbit(back[0]), f"Sign bit roundtrip failed for {dtype} with value {val}"
5553+
assert np.signbit(back[0]) == np.signbit(q[0]), f"Sign bit roundtrip failed for {dtype} with value {val}"
55555554
if np.isnan(q[0]):
55565555
assert np.isnan(back[0]), f"NaN roundtrip failed for {dtype}"
55575556
else:
@@ -5566,8 +5565,7 @@ def test_same_value_cast_strings_narrow_width(self, dtype):
55665565
q = np.array([val], dtype=QuadPrecDType())
55675566
result = q.astype(dtype, casting="same_value")
55685567
back = result.astype(QuadPrecDType())
5569-
if str(val).startswith("-"):
5570-
assert np.signbit(back[0]), f"Sign bit roundtrip failed for {dtype} with value {val}"
5568+
assert np.signbit(back[0]) == np.signbit(q[0]), f"Sign bit roundtrip failed for {dtype} with value {val}"
55715569
if np.isnan(q[0]):
55725570
assert np.isnan(back[0])
55735571
else:
@@ -5607,8 +5605,7 @@ def test_quad_to_quad_same_value_casting_passing(self, src_backend, dst_backend)
56075605
result = src.astype(QuadPrecDType(backend=dst_backend), casting="same_value")
56085606

56095607
# Verify value is preserved
5610-
if str(val).startswith("-"):
5611-
assert np.signbit(result[0]), f"Sign bit failed for {val} in {src_backend} -> {dst_backend}"
5608+
assert np.signbit(result[0]) == np.signbit(src[0]), f"Sign bit failed for {val} in {src_backend} -> {dst_backend}"
56125609
if val in ["nan", "-nan"] :
56135610
assert np.isnan(result[0])
56145611
else:

0 commit comments

Comments
 (0)