It seems to happen all the time. For example:
(apply * (range 1 101))
gives me the error
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
While in Ruby 1.9.2 the (conceptually) equivalent code,
(1..100).reduce(:*)
produces the desired result of
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Obviously the two languages are quite different under the hood but it seems like they should both be able to handle this calculation without issue. Am I doing something wrong here? Or do I have an incorrect understanding?
Avoidance. By allocating variables with data types that are large enough to contain all values that may possibly be computed and stored in them, it is always possible to avoid overflow.
If it overflows, it goes back to the minimum value and continues from there. If it underflows, it goes back to the maximum value and continues from there. If you think that this may occur more than often, then consider using a datatype or object which can store larger values, e.g. long or maybe java. math.
You need to use some form of BigInteger.
Try (apply *' (range 1 101))
.
(see http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics -- evidently this auto-promotes upon overflow?)
From Clojure 1.3, you should cast Integer(or Long) to BigInt explicitly, otherwise there will be "ArithmeticException integer overflow" error when the number is too large.
There are three solutions, please pick the one you favor:
use one of the auto-promoting math functions:+', -', *', /', inc', dec'
example: (apply *' (range 1 101))
use the BigInt type cast function
example: (apply * (range (bigint 1) 101))
change to BigInt numeric literal
example: (apply * (range 1N 101))
Reference: Documentation for Clojure 1.3 Numerics
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With