@@ -15,13 +15,18 @@ Base.parent(r::RangeCumsum) = r.range
1515== (a:: RangeCumsum , b:: RangeCumsum ) = a. range == b. range
1616BroadcastStyle (:: Type{<:RangeCumsum{<:Any,RR}} ) where RR = BroadcastStyle (RR)
1717
18- _half (x:: Integer ) = x ÷ 2
19- _half (x) = x / 2
18+ function _half_prod (a:: Integer , b:: Integer )
19+ iseven (a) ? (a÷ 2 ) * b : a * (b÷ 2 )
20+ end
21+ function _onethird_prod (a:: Integer , b:: Integer )
22+ mod (a, 3 ) == 0 ? (a÷ 3 ) * b : a * (b÷ 3 )
23+ end
2024
2125function _getindex (r:: AbstractRange{<:Real} , k)
2226 v = first (r)
2327 s = step (r)
24- _half (k * (2 v - s + s* k))
28+ # avoid overflow, if possible
29+ k * v + s * _half_prod (k, k- 1 )
2530end
2631Base. @propagate_inbounds _getindex (r:: AbstractRange , k) = sum (r[range (firstindex (r), length= k)])
2732
@@ -44,7 +49,9 @@ function Base.sum(r::RangeCumsum{<:Real})
4449 N = length (r)
4550 v = first (r)
4651 s = step (r. range)
47- _half ((2 v- s)* (N* (N+ 1 )÷ 2 ) + s* (N* (N+ 1 )* (2 N+ 1 )÷ 6 ))
52+ # avoid overflow, if possible
53+ halfnnp1 = _half_prod (N, N+ 1 )
54+ v * halfnnp1 + s * _onethird_prod (halfnnp1, N- 1 )
4855end
4956
5057union (a:: RangeCumsum{<:Any,<:OneTo} , b:: RangeCumsum{<:Any,<:OneTo} ) =
0 commit comments