12
12
const SmallUnsigned = Union{UInt8,UInt16,UInt32}
13
13
end
14
14
15
- # Certain reductions like sum and prod may wish to promote the items being
16
- # reduced over to an appropriate size.
17
- promote_sys_size (x) = x
18
- promote_sys_size (x:: Union{Bool, SmallSigned} ) = Int (x)
19
- promote_sys_size (x:: SmallUnsigned ) = UInt (x)
15
+ # Certain reductions like sum and prod may wish to promote the items being reduced over to
16
+ # an appropriate size. Note we need x + zero(x) because some types like Bool have their sum
17
+ # lie in a larger type.
18
+ promote_sys_size (T:: Type ) = T
19
+ promote_sys_size (:: Type{<:SmallSigned} ) = Int
20
+ promote_sys_size (:: Type{<:SmallUnsigned} ) = UInt
21
+
22
+ promote_sys_size_add (x) = convert (promote_sys_size (typeof (x + zero (x))), x)
23
+ promote_sys_size_mul (x) = convert (promote_sys_size (typeof (x * one (x))), x)
24
+ const _PromoteSysSizeFunction = Union{typeof (promote_sys_size_add),
25
+ typeof (promote_sys_size_mul)}
20
26
21
27
# # foldl && mapfoldl
22
28
@@ -240,8 +246,8 @@ reduce_empty(::typeof(|), ::Type{Bool}) = false
240
246
241
247
mapreduce_empty (f, op, T) = _empty_reduce_error ()
242
248
mapreduce_empty (:: typeof (identity), op, T) = reduce_empty (op, T)
243
- mapreduce_empty (:: typeof (promote_sys_size) , op, T) =
244
- promote_sys_size (mapreduce_empty (identity, op, T))
249
+ mapreduce_empty (f :: _PromoteSysSizeFunction , op, T) =
250
+ f (mapreduce_empty (identity, op, T))
245
251
mapreduce_empty (:: typeof (abs), :: typeof (+ ), T) = abs (zero (T))
246
252
mapreduce_empty (:: typeof (abs2), :: typeof (+ ), T) = abs2 (zero (T))
247
253
mapreduce_empty (:: typeof (abs), :: Union{typeof(scalarmax), typeof(max)} , T) =
@@ -251,8 +257,8 @@ mapreduce_empty(::typeof(abs2), ::Union{typeof(scalarmax), typeof(max)}, T) =
251
257
252
258
# Allow mapreduce_empty to “see through” promote_sys_size
253
259
let ComposedFunction = typename (typeof (identity ∘ identity)). wrapper
254
- global mapreduce_empty (f:: ComposedFunction{typeof(promote_sys_size) } , op, T) =
255
- promote_sys_size (mapreduce_empty (f. g, op, T))
260
+ global mapreduce_empty (f:: ComposedFunction{<:_PromoteSysSizeFunction } , op, T) =
261
+ f . f (mapreduce_empty (f. g, op, T))
256
262
end
257
263
258
264
mapreduce_empty_iter (f, op, itr, :: HasEltype ) = mapreduce_empty (f, op, eltype (itr))
@@ -366,7 +372,7 @@ In the former case, the integers are widened to system word size and therefore
366
372
the result is 128. In the latter case, no such widening happens and integer
367
373
overflow results in -128.
368
374
"""
369
- sum (f:: Callable , a) = mapreduce (promote_sys_size ∘ f, + , a)
375
+ sum (f:: Callable , a) = mapreduce (promote_sys_size_add ∘ f, + , a)
370
376
371
377
"""
372
378
sum(itr)
@@ -382,7 +388,7 @@ julia> sum(1:20)
382
388
210
383
389
```
384
390
"""
385
- sum (a) = mapreduce (promote_sys_size , + , a)
391
+ sum (a) = mapreduce (promote_sys_size_add , + , a)
386
392
sum (a:: AbstractArray{Bool} ) = count (a)
387
393
388
394
@@ -397,7 +403,7 @@ summation algorithm for additional accuracy.
397
403
"""
398
404
function sum_kbn (A)
399
405
T = _default_eltype (typeof (A))
400
- c = promote_sys_size (zero (T):: T )
406
+ c = promote_sys_size_add (zero (T):: T )
401
407
i = start (A)
402
408
if done (A, i)
403
409
return c
@@ -432,7 +438,7 @@ julia> prod(abs2, [2; 3; 4])
432
438
576
433
439
```
434
440
"""
435
- prod (f:: Callable , a) = mapreduce (promote_sys_size ∘ f, * , a)
441
+ prod (f:: Callable , a) = mapreduce (promote_sys_size_mul ∘ f, * , a)
436
442
437
443
"""
438
444
prod(itr)
@@ -448,7 +454,7 @@ julia> prod(1:20)
448
454
2432902008176640000
449
455
```
450
456
"""
451
- prod (a) = mapreduce (promote_sys_size , * , a)
457
+ prod (a) = mapreduce (promote_sys_size_mul , * , a)
452
458
453
459
# # maximum & minimum
454
460
0 commit comments