27
Hugs> 94535^445
1376320882321377050696053887661515621104890164005282153069726424773999801846841903244827702943487982707454966009456016735041878000604143500908532887464920380605164932112687039059526672109818924234920844448231612532570718657160234177285377733830104834041049076609912488237219608445995072867798430614935403219495883835042862802917980856774134757390782052200512932375660858045003581611863121089979673784484701791210379500218604466721285456487387736825167702127154268533859979529612671925052419513844416493584817268143587955662039327860394141299238613042312035808541735213479394437496215520277526351425482512084759462579494878772787079101513841720202004639843443083454387175700954018825292148776647553122504118229978165851660083576570848983047255050145168802863168613110619584686348869690774233051669081248424584219383477237544209892290799448207462345346336076966775224683516220960618177284844330167142846351091001423033864986042919757795382577032341453971393897073354841924116635150129850119992031076354249371062307034564093077675129303383786693131843907104175619570678630497198824622804914508555467550904967368926176118094672479099827962889569753303773699017596074205893197641101210911874606040804983166177455705972192827752532495287749766682029353154226049380290040508900715169403153139668217790502306177709467234413947747673881158973344492079455405942662489751581189327200960698310350121179918845099840977270519116578719881752429190273998774113278822810866144521416958558406602325070095207349450759264393913367193083149679216066539911941983836313340998945139132421885688290888674594474605510238217590823316979504437667252929278291853368754482552573193289277120902144178425726693671235675042499401282016643202758246845332593475338220708351934511933096882598943512036679145593929114103343255708217768511665236173107020739195152050863630870948954052925049746246549772984384435109578859863612603574306739909728739428192798727373799081111333186135697868385292787575475482883660605162944306327057220313320376280182432763977906971557137715710757099478269250731209785404487629107297262798803645379809868663503452656912571816192881412782623078761411808958183665272686617730596943579533808499348879195167683064937591552734375

为什么 Haskell 可以计算出这么大的数字,而其他语言,例如 Java,却不能(那么容易)?

4

8 回答 8

45

这是设计理念的不同

  • Haskell 的设计者希望确保用户不会对需要超过 32 位的整数计算的看似任意的失败感到惊讶。

  • Java 的设计者希望确保用户不会对由于对需要超过 32 位的整数进行大量计算而导致的看似随意的性能下降感到惊讶。

在每种语言中,您都必须做一些特殊的事情才能获得另一种整数。

默认情况下支持任意大整数的语言有着悠久而光荣的历史。我最喜欢的两个是IconSmalltalk,它们都超过 25 岁了。

于 2009-07-26T17:18:45.290 回答
28

Java 有BigInteger类。

它本可以将这种功能内置到语言中,但是(像许多语言一样)它倾向于使原始特征紧密映射到 CPU 支持的事物上。

另一方面,Haskell 强调数学符号风格的表现力,其中“性能”考虑在很大程度上无关紧要。

于 2009-07-26T11:22:07.593 回答
13

Haskell 中的数字字面量是重载的,因此它们可以表示多种具体类型(如IntIntegerFloat什至MyOwnNumber)。

您可以通过提供类型信息手动选择特定类型,如下所示:

x = 4 :: Int
y = 4 :: Integer
z = 4 :: Float

这三个值具有不同的类型,对它们执行的操作将表现不同。

an 的确切大小Int取决于实现,但可以是 28 位,这种类型的行为类似于 Java 原语int,例如它会溢出。

AnInteger是一种可以包含任意精度整数的类型,例如 Java BigInteger

而 aFloat就像 Java 一样float,使用浮点运算。

就像数字文字一样,许多运算符也被重载(使用类型类),因此可以与不同的类型一起使用。因此+运算符可以同时使用Ints 和Floats。

在您的情况下,由于您没有提供任何类型信息,解释器将默认为该Integer类型。这意味着对于^操作员,它也会选择Integer实例。允许任意精度的整数计算。

于 2009-07-26T13:00:04.200 回答
6

Java 具有“原始数据类型”(处理器支持的类型)的概念,这些概念与所有其他类不同。

在 Haskell 中,Int是一个和所有其他类型一样的类型,因此它很容易成为( )中使用的NumIntegral类型类的成员。这些类型类的另一个成员是,它支持所有大小的整数(只要您有足够的内存存储它们的数字)。(^)"(^) :: (Num a, Integral b) => a -> b -> a"Integer

在 Java 中,您可以使用许多“大数字”库,但它们的操作不会使用您习惯的中缀运算符,因为它们仅适用于 Java 中的“原始类型”。

于 2009-07-26T11:41:09.567 回答
3

简短而基本的答案是它们实现了默认整数差异。在 Java 中,标准的 int 是 32 位的。已签名,这为您提供了−2,147,483,648to的范围+2,147,483,647

也就是说,Java 也有bignum类。如果您使用这些,您还将获得使用任意大数字的能力。

于 2009-07-26T11:20:44.210 回答
1

如前所述,如果您有 32 位字并使用完整范围,则使用二进制补码得到 -2^31 到 2^31-1。

通过保留字的几位,这些位可用于携带该值的类型信息。也就是说,值在运行时“知道”它们自己的类型。其余位用于携带值的数据。

适合这些剩余位的整数值可以直接存储在字中。这样的整数通常称为“fixnums”。如果它们不适合,则字的类型位指示它是“bigint”,其余位用于将内存指针存储到存储 bigint 值的堆中。

编译器需要将您的算术表达式转换为涵盖操作数允许类型组合的多个代码路径。添加示例:

  • 固定编号 + 固定编号
  • bigint + fixnum
  • 固定数字 + 大整数
  • 大整数 + 大整数

这些语言的编译器中的许多优化都集中在避免使这项工作所需的运行时类型检查的开销。通常还有一些方法可以明确地告诉编译器从 fixnum 到 bignum 的自动降级是不希望的,而是需要 32 位整数的溢出行为。这对于有效地实现密码算法非常重要。

于 2009-07-26T12:44:38.033 回答
0

这是如何编码数字的问题。执行此操作的传统方法是使用给定位数对数字进行编码,而您无法获得无限的准确性。Haskell 显然使用可变数量的位数来执行此操作,这也很好,但通常意味着所有数学都在软件中完成,因为硬件加速通常仅适用于有限精度。

于 2009-07-26T11:21:59.513 回答
0

您可以使用 BigInteger 来做同样的事情。Haskell 是一种比 Java 更简洁的函数式语言。

我们有这么多语言的一个原因是不同的语言在不同的任务上表现更好,因为它们是根据不同的假设设计的。大多数函数式语言在数学函数方面更简单,但往往在其他用例上遇到困难,例如,haskell 不太可能是编写 GUI 的好选择。

于 2009-07-26T11:22:16.127 回答