From 2aea92c89db779a67b8d0fc03bf2a8fe97d11c9f Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 2 Oct 2026 18:07:28 +0800 Subject: [PATCH 1/3] Use integer arithmetic for ND slice lengths --- cpp/nd/impl/sliced_array.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cpp/nd/impl/sliced_array.hpp b/cpp/nd/impl/sliced_array.hpp index ba6be0b4d3..84d15fd38f 100644 --- a/cpp/nd/impl/sliced_array.hpp +++ b/cpp/nd/impl/sliced_array.hpp @@ -7,6 +7,8 @@ #include #include +#include + namespace { template @@ -222,7 +224,20 @@ class sliced_array if (step < 0) { should_reverse = true; } - dim = std::ceil((stop - start) / static_cast(step)); + if constexpr (std::is_integral_v) { + const auto start64 = static_cast(start); + const auto stop64 = static_cast(stop); + const auto step64 = static_cast(step); + if (step64 > 0 && stop64 > start64) { + dim = 1 + (stop64 - start64 - 1) / step64; + } else if (step64 < 0 && stop64 < start64) { + const auto distance = static_cast(start64) - static_cast(stop64); + const auto step_magnitude = uint64_t{0} - static_cast(step64); + dim = static_cast(1 + (distance - 1) / step_magnitude); + } + } else { + dim = std::ceil((stop - start) / static_cast(step)); + } } new_shape[i] = std::max(dim, static_cast(0)); From 45b14fc8e41183a9bc8b761930629cfad608dd84 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Mon, 5 Oct 2026 15:56:02 +0800 Subject: [PATCH 2/3] Preserve unsigned slice steps above int64 range --- cpp/nd/impl/sliced_array.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cpp/nd/impl/sliced_array.hpp b/cpp/nd/impl/sliced_array.hpp index 84d15fd38f..e399854f36 100644 --- a/cpp/nd/impl/sliced_array.hpp +++ b/cpp/nd/impl/sliced_array.hpp @@ -227,13 +227,20 @@ class sliced_array if constexpr (std::is_integral_v) { const auto start64 = static_cast(start); const auto stop64 = static_cast(stop); - const auto step64 = static_cast(step); - if (step64 > 0 && stop64 > start64) { - dim = 1 + (stop64 - start64 - 1) / step64; - } else if (step64 < 0 && stop64 < start64) { - const auto distance = static_cast(start64) - static_cast(stop64); - const auto step_magnitude = uint64_t{0} - static_cast(step64); - dim = static_cast(1 + (distance - 1) / step_magnitude); + if constexpr (std::is_unsigned_v) { + const auto step64 = static_cast(step); + if (stop64 > start64) { + dim = static_cast(1 + (stop64 - start64 - 1) / step64); + } + } else { + const auto step64 = static_cast(step); + if (step64 > 0 && stop64 > start64) { + dim = 1 + (stop64 - start64 - 1) / step64; + } else if (step64 < 0 && stop64 < start64) { + const auto distance = static_cast(start64) - static_cast(stop64); + const auto step_magnitude = uint64_t{0} - static_cast(step64); + dim = static_cast(1 + (distance - 1) / step_magnitude); + } } } else { dim = std::ceil((stop - start) / static_cast(step)); From 26e3d779bd7cf1fea68b8afbb92adafed5f15fc7 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Mon, 5 Oct 2026 15:58:24 +0800 Subject: [PATCH 3/3] Revert "Preserve unsigned slice steps above int64 range" This reverts commit 45b14fc8e41183a9bc8b761930629cfad608dd84. --- cpp/nd/impl/sliced_array.hpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/cpp/nd/impl/sliced_array.hpp b/cpp/nd/impl/sliced_array.hpp index e399854f36..84d15fd38f 100644 --- a/cpp/nd/impl/sliced_array.hpp +++ b/cpp/nd/impl/sliced_array.hpp @@ -227,20 +227,13 @@ class sliced_array if constexpr (std::is_integral_v) { const auto start64 = static_cast(start); const auto stop64 = static_cast(stop); - if constexpr (std::is_unsigned_v) { - const auto step64 = static_cast(step); - if (stop64 > start64) { - dim = static_cast(1 + (stop64 - start64 - 1) / step64); - } - } else { - const auto step64 = static_cast(step); - if (step64 > 0 && stop64 > start64) { - dim = 1 + (stop64 - start64 - 1) / step64; - } else if (step64 < 0 && stop64 < start64) { - const auto distance = static_cast(start64) - static_cast(stop64); - const auto step_magnitude = uint64_t{0} - static_cast(step64); - dim = static_cast(1 + (distance - 1) / step_magnitude); - } + const auto step64 = static_cast(step); + if (step64 > 0 && stop64 > start64) { + dim = 1 + (stop64 - start64 - 1) / step64; + } else if (step64 < 0 && stop64 < start64) { + const auto distance = static_cast(start64) - static_cast(stop64); + const auto step_magnitude = uint64_t{0} - static_cast(step64); + dim = static_cast(1 + (distance - 1) / step_magnitude); } } else { dim = std::ceil((stop - start) / static_cast(step));