它似乎一直都在发生.例如:
(apply * (range 1 101))
Run Code Online (Sandbox Code Playgroud)
给了我错误
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
Run Code Online (Sandbox Code Playgroud)
而在Ruby 1.9.2中(概念上)等效代码,
(1..100).reduce(:*)
Run Code Online (Sandbox Code Playgroud)
产生预期的结果
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
显然,这两种语言在引擎盖下是完全不同的,但似乎它们都应该能够毫无问题地处理这种计算.我在这里做错了吗?或者我的理解不正确?
Ste*_*ang 37
您需要使用某种形式的BigInteger.
试试(apply *' (range 1 101))
.
(参见http://dev.clojure.org/display/doc/Documentation+for+3.3+Numerics - 显然这会在溢出时自动升级?)
Ruby具有自动提升计算,当结果溢出其类型时,会更改为更大的位类型数.由于性能方面的考虑,从Clojure的1.3提高计算不会自动提升,你需要考虑到,如果一个计算可以溢出,或使用自动推进的数学函数(+'
,-'
,*'
,/'
)如果性能不会是一个问题.
从Clojure 1.3开始,你应该明确地将Integer(或Long)强制转换为BigInt,否则当数字太大时会出现"ArithmeticException integer overflow"错误.
有三种解决方案,请选择您喜欢的解决方案:
使用其中一个自动提升数学函数:+', -', *', /', inc', dec'
例: (apply *' (range 1 101))
使用BigInt类型的强制转换函数
例: (apply * (range (bigint 1) 101))
更改为BigInt数字文字
例: (apply * (range 1N 101))
归档时间: |
|
查看次数: |
5913 次 |
最近记录: |