Skip to content

Instantly share code, notes, and snippets.

@endo64
Last active August 9, 2018 22:49
Show Gist options
  • Save endo64/e0ea49bc2fb09d548bad1b077720eda5 to your computer and use it in GitHub Desktop.
Save endo64/e0ea49bc2fb09d548bad1b077720eda5 to your computer and use it in GitHub Desktop.
Sum function for Red
Red []
do %profile.red
sum1: func [
"Return sum of numbers in a block" b /safe "Coerce to return float in case of overflow" /local s v
] [
s: 0
foreach v b [
all [
safe
not float? s
any [
all [
positive? v
2147483647 - v < s
]
all [
negative? v
-2147483648 - v > s
]
]
s: to float! s
]
s: s + v
]
s
]
sum3: func [
"Return sum of numbers in a block" b /safe "Coerce to return float in case of overflow" /local s v
] [
s: 0
foreach v b [
all [
safe
not float? s
any [
all [
v > 0
2147483647 - v < s
]
all [
v < 0
-2147483648 - v > s
]
]
s: s + 0.0
]
s: s + v
]
s
]
sum2: func ["Return sum of numbers in a block" b /local s v] [s: 0 foreach v b [s: s + v]]
;tests
print [type? i: sum1/safe [1 2 3] tab i]
print [type? i: sum1/safe [2147483647 0] tab i]
print [type? i: sum1/safe [2147483647 1] tab i]
print [type? i: sum1/safe [-2147483648 -1] tab i]
;profile
b: collect [loop 1000000 [keep random 100]]
profile/show [ [sum1 b] [sum2 b] [sum1/safe b] [sum3/safe b] ]
;integer 6
;integer 2147483647
;float 2147483648.0
;float -2147483649.0
;Time | Memory | Code
;--------------------------------------------------
;1.0x (396ms) | 0 | [sum2 b]
;1.65x (652ms) | 0 | [sum1 b]
;6.59x (0:00:02.611) | 0 | [sum3/safe b]
;6.82x (0:00:02.7) | 0 | [sum1/safe b]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment