Skip to content

Commit e374a36

Browse files
committed
fixed string same_value
1 parent 8862c23 commit e374a36

2 files changed

Lines changed: 56 additions & 56 deletions

File tree

quaddtype/numpy_quaddtype/src/casts.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ quad_to_string_adaptive_cstr(Sleef_quad *sleef_val, npy_intp unicode_size_chars)
380380
* @return 1 if same_value check passes, -1 if it fails (sets Python error)
381381
*/
382382
static inline int
383-
quad_to_string_same_value_check(quad_value in_val, const char *str_buf, npy_intp str_len,
383+
quad_to_string_same_value_check(const quad_value *in_val, const char *str_buf, npy_intp str_len,
384384
QuadBackendType backend)
385385
{
386386
char *truncated_str = (char *)malloc(str_len + 1);
@@ -408,28 +408,28 @@ quad_to_string_same_value_check(quad_value in_val, const char *str_buf, npy_intp
408408
// Compare original and roundtripped values
409409
if (backend == BACKEND_SLEEF) {
410410
// NaN == NaN for same_value purposes
411-
if (Sleef_iunordq1(in_val.sleef_value, roundtrip.sleef_value))
411+
if (Sleef_iunordq1(in_val->sleef_value, roundtrip.sleef_value))
412412
return 1;
413-
if (Sleef_icmpeqq1(in_val.sleef_value, roundtrip.sleef_value))
413+
if (Sleef_icmpeqq1(in_val->sleef_value, roundtrip.sleef_value))
414414
return 1;
415415
// Handle -0.0 == +0.0 case
416-
if (Sleef_icmpeqq1(in_val.sleef_value, QUAD_ZERO) &&
416+
if (Sleef_icmpeqq1(in_val->sleef_value, QUAD_ZERO) &&
417417
Sleef_icmpeqq1(roundtrip.sleef_value, QUAD_ZERO))
418418
return 1;
419419
}
420420
else {
421-
if (std::isnan(in_val.longdouble_value) && std::isnan(roundtrip.longdouble_value))
421+
if (std::isnan(in_val->longdouble_value) && std::isnan(roundtrip.longdouble_value))
422422
return 1;
423-
if (in_val.longdouble_value == roundtrip.longdouble_value)
423+
if (in_val->longdouble_value == roundtrip.longdouble_value)
424424
return 1;
425425
// Handle -0.0 == +0.0 case
426-
if (in_val.longdouble_value == 0.0L && roundtrip.longdouble_value == 0.0L)
426+
if (in_val->longdouble_value == 0.0L && roundtrip.longdouble_value == 0.0L)
427427
return 1;
428428
}
429429

430430
// Values don't match - the string width is too narrow for exact representation
431431
// Sleef_quad sleef_val = quad_to_sleef_quad(&in_val, backend);
432-
Sleef_quad sleef_val = in_val.sleef_value;
432+
Sleef_quad sleef_val = in_val->sleef_value;
433433
const char *val_str = quad_to_string_adaptive_cstr(&sleef_val, QUAD_STR_WIDTH);
434434
if (val_str != NULL) {
435435
PyErr_Format(PyExc_ValueError,
@@ -479,7 +479,7 @@ quad_to_unicode_loop(PyArrayMethod_Context *context, char *const data[],
479479

480480
// Perform same_value check if requested
481481
if (same_value_casting) {
482-
if (quad_to_string_same_value_check(in_val, temp_str, str_len, backend) < 0) {
482+
if (quad_to_string_same_value_check(&in_val, temp_str, str_len, backend) < 0) {
483483
return -1;
484484
}
485485
}
@@ -670,7 +670,7 @@ quad_to_bytes_loop(PyArrayMethod_Context *context, char *const data[],
670670

671671
// Perform same_value check if requested
672672
if (same_value_casting) {
673-
if (quad_to_string_same_value_check(in_val, temp_str, str_len, backend) < 0) {
673+
if (quad_to_string_same_value_check(&in_val, temp_str, str_len, backend) < 0) {
674674
return -1;
675675
}
676676
}
@@ -830,7 +830,7 @@ quad_to_stringdtype_strided_loop(PyArrayMethod_Context *context, char *const dat
830830

831831
// Perform same_value check if requested
832832
if (same_value_casting) {
833-
if (quad_to_string_same_value_check(in_val, str_buf, str_size, backend) < 0) {
833+
if (quad_to_string_same_value_check(&in_val, str_buf, str_size, backend) < 0) {
834834
NpyString_release_allocator(allocator);
835835
return -1;
836836
}

quaddtype/tests/test_quaddtype.py

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5527,48 +5527,48 @@ def test_same_value_cast_floats_precision_loss(self, dtype):
55275527
with pytest.raises(ValueError):
55285528
q.astype(dtype, casting="same_value")
55295529

5530-
# @pytest.mark.parametrize("dtype", [
5531-
# "S50", "U50", "<U50", "S100", "U100", np.dtypes.StringDType()
5532-
# ])
5533-
# def test_same_value_cast_strings_enough_width(self, dtype):
5534-
# """Test that string types with enough width can represent quad values exactly."""
5535-
# values = [
5536-
# "0.0", "-0.0", "1.0", "-1.0",
5537-
# "3.14159265358979323846264338327950288", # pi with full quad precision
5538-
# "inf", "-inf", "nan",
5539-
# "1.23e100", "-4.56e-100",
5540-
# ]
5541-
5542-
# for val in values:
5543-
# q = np.array([val], dtype=QuadPrecDType())
5544-
# result = q.astype(dtype, casting="same_value")
5545-
# # Convert back and verify
5546-
# back = result.astype(QuadPrecDType())
5547-
# if np.isnan(q[0]):
5548-
# assert np.isnan(back[0]), f"NaN roundtrip failed for {dtype}"
5549-
# else:
5550-
# assert q[0] == back[0], f"Value {val} roundtrip failed for {dtype}"
5551-
5552-
# @pytest.mark.parametrize("dtype", ["S10", "U10", "<U10"])
5553-
# def test_same_value_cast_strings_narrow_width(self, dtype):
5554-
# """Test that string types with narrow width fail for values that need more precision."""
5555-
# # Values that can fit in 10 chars should pass
5556-
# passing_values = ["0.0", "1.0", "-1.0", "inf", "-inf", "nan"]
5557-
# for val in passing_values:
5558-
# q = np.array([val], dtype=QuadPrecDType())
5559-
# result = q.astype(dtype, casting="same_value")
5560-
# back = result.astype(QuadPrecDType())
5561-
# if np.isnan(q[0]):
5562-
# assert np.isnan(back[0])
5563-
# else:
5564-
# assert q[0] == back[0], f"Value {val} should roundtrip in {dtype}"
5565-
5566-
# # Values that need more than 10 chars should fail
5567-
# failing_values = [
5568-
# "3.14159265358979323846264338327950288", # pi
5569-
# "1.23456789012345", # needs > 10 chars
5570-
# ]
5571-
# for val in failing_values:
5572-
# q = np.array([val], dtype=QuadPrecDType())
5573-
# with pytest.raises(ValueError):
5574-
# q.astype(dtype, casting="same_value")
5530+
@pytest.mark.parametrize("dtype", [
5531+
"S50", "U50", "<U50", "S100", "U100", np.dtypes.StringDType()
5532+
])
5533+
def test_same_value_cast_strings_enough_width(self, dtype):
5534+
"""Test that string types with enough width can represent quad values exactly."""
5535+
values = [
5536+
"0.0", "-0.0", "1.0", "-1.0",
5537+
"3.14159265358979323846264338327950288", # pi with full quad precision
5538+
"inf", "-inf", "nan",
5539+
"1.23e100", "-4.56e-100",
5540+
]
5541+
5542+
for val in values:
5543+
q = np.array([val], dtype=QuadPrecDType())
5544+
result = q.astype(dtype, casting="same_value")
5545+
# Convert back and verify
5546+
back = result.astype(QuadPrecDType())
5547+
if np.isnan(q[0]):
5548+
assert np.isnan(back[0]), f"NaN roundtrip failed for {dtype}"
5549+
else:
5550+
assert q[0] == back[0], f"Value {val} roundtrip failed for {dtype}"
5551+
5552+
@pytest.mark.parametrize("dtype", ["S10", "U10", "<U10"])
5553+
def test_same_value_cast_strings_narrow_width(self, dtype):
5554+
"""Test that string types with narrow width fail for values that need more precision."""
5555+
# Values that can fit in 10 chars should pass
5556+
passing_values = ["0.0", "1.0", "-1.0", "inf", "-inf", "nan"]
5557+
for val in passing_values:
5558+
q = np.array([val], dtype=QuadPrecDType())
5559+
result = q.astype(dtype, casting="same_value")
5560+
back = result.astype(QuadPrecDType())
5561+
if np.isnan(q[0]):
5562+
assert np.isnan(back[0])
5563+
else:
5564+
assert q[0] == back[0], f"Value {val} should roundtrip in {dtype}"
5565+
5566+
# Values that need more than 10 chars should fail
5567+
failing_values = [
5568+
"3.14159265358979323846264338327950288", # pi
5569+
"1.23456789012345", # needs > 10 chars
5570+
]
5571+
for val in failing_values:
5572+
q = np.array([val], dtype=QuadPrecDType())
5573+
with pytest.raises(ValueError):
5574+
q.astype(dtype, casting="same_value")

0 commit comments

Comments
 (0)