Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Get List Reduce To Throw Arithmetic Overflow

Tags:

f#

So, yesterday while working through some F# code as part of a coding exercise, another developer pointed out something interesting. We were just doing a quick piece of code to demonstrate summing a list. If I do:

[1..100000] |> Seq.sum

I get the following error:

System.OverflowException: Arithmetic operation resulted in an overflow.
   at <StartupCode$FSI_0003>.$FSI_0003.main@()
Stopped due to error

However, if I do:

[1..100000] |> List.reduce (+)

I get:

val it : int = 705082704

I realize although these two pieces of code should accomplish the same purpose they are very different. I am just curious is there a way to get the List.reduce to throw the OverflowException rather than giving me a bad answer?

like image 491
Onorio Catenacci Avatar asked Aug 20 '13 14:08

Onorio Catenacci


People also ask

How do you handle arithmetic overflow?

If you want to ensure that arithmetic operations will throw overflow exceptions if an overflow happens, you need to use the checked { ... } code block. When using the checked { ... } code block, if any arithmetic operation causes an overflow, an OverflowException will be thrown, and will need to be catched and handled.

Which interrupt is used for arithmetic overflow?

1 Microprocessor interrupts These interrupts are initiated by various error conditions (such as a division by zero or arithmetic overflow). These interrupts are also known as processor exceptions.

Is arithmetic overflow an exception?

An OverflowException is thrown at run time under the following conditions: An arithmetic operation produces a result that is outside the range of the data type returned by the operation.

What is meant by arithmetic overflow?

An arithmetic overflow is the result of a calculation that exceeds the memory space designated to hold it. For example, a divide-by-zero yields a much larger result. See arithmetic underflow.


2 Answers

You can use a checked operator:

[1..100000] |> List.reduce (Checked.(+))
like image 96
Matthew Mcveigh Avatar answered Nov 02 '22 23:11

Matthew Mcveigh


From the f# source code

[<CompiledName("Sum")>]
let inline sum (source: seq< (^a) >) : ^a = 
  use e = source.GetEnumerator() 
  let mutable acc = LanguagePrimitives.GenericZero< (^a) >
  while e.MoveNext() do
      acc <- Checked.(+) acc e.Current
  acc

Notice the Checked.(operator) this checks for arithmetic overflows…

http://msdn.microsoft.com/en-us/library/vstudio/ee340296.aspx

like image 21
Tyler Smith Avatar answered Nov 03 '22 00:11

Tyler Smith