【问题标题】:Long only allows 10^9 on scalafiddleLong 在 scalafiddle 上只允许 10^9
【发布时间】:2020-09-24 00:32:27
【问题描述】:

问题陈述:

Scala.Long 应该处理到 9223372036854775807 的正整数,但是 scalafiddle.io 只允许 10^9 数量级的整数

参考:

https://www.scala-lang.org/api/2.12.6/scala/Long.html

https://www.tutorialspoint.com/scala/scala_data_types.htm

代码:

def fib(n:Int):Long={

  @tailrec def fibTail( n: Int, a:Int, b:Int): Long = n match {
    case 0 => a 
    case _ => fibTail( n-1, b, a+b )
  }
  return fibTail( n, 0, 1)
}

//test cases
for (tryit<-1 to 10) println(tryit + ": " + fib(tryit))
for (breakit<-10 to 100 by 10) println(breakit + ": " + fib(breakit))
for (overflow<-1 to 8) println("10^" + overflow + ": " + fib(math.pow(10,overflow).toInt))

scalafiddle.io 上的代码输出


斐波那契


1:1 2:1 3:2 4:3 5:5 6:8 7:13 8:21 9:34 10:55 10:55 20: 6765 30: 832040 40: 102334155 50:-298632863 60: 1820529360 70: 885444751 80:-285007387 90:-1581614984 100:-980107325 10^1: 55 10^2:-980107325 10^3: 1556111435 10^4: 1242044891 10^5: 873876091 10^6: 1884755131 10^7:-1448735941 10^8: 1819143227

问题:

这是 scalafiddle 环境的产物还是我做错了什么?

【问题讨论】:

    标签: scala types long-integer


    【解决方案1】:

    您不是在 Long 上进行计算,而是在任何地方使用 Int,并且只有在完成后才将结果扩大到 Long。如果你真的使用Long,像这样:

    def fib(n:Long):Long={
    
      @tailrec def fibTail( n: Long, a:Long, b:Long): Long = n match {
        case 0 => a 
        case _ => fibTail( n-1, b, a+b )
      }
      return fibTail( n, 0, 1)
    }
    

    然后整数溢出似乎要晚一点发生

    @ for (tryit<-1 to 10) println(tryit + ": " + fib(tryit))
    1: 1
    2: 1
    3: 2
    4: 3
    5: 5
    6: 8
    7: 13
    8: 21
    9: 34
    10: 55
    
    
    @ for (breakit<-10 to 100 by 10) println(breakit + ": " + fib(breakit))
    10: 55
    20: 6765
    30: 832040
    40: 102334155
    50: 12586269025
    60: 1548008755920
    70: 190392490709135
    80: 23416728348467685
    90: 2880067194370816120
    100: 3736710778780434371
    
    
    @ for (overflow<-1 to 8) println("10^" + overflow + ": " + fib(math.pow(10,overflow).toLong))
    10^1: 55
    10^2: 3736710778780434371
    10^3: 817770325994397771
    10^4: -2872092127636481573
    10^5: 2754320626097736315
    10^6: -4249520595888827205
    10^7: -8398834052292539589
    10^8: -4307732722963583941
    

    但即使Long fib 在 10^1 和 10^2 之间溢出,我们可以看到如果我们使用 BigInt 实现:

    @ def fib(n: BigInt): BigInt = {
        @scala.annotation.tailrec def fibTail( n: BigInt, a:BigInt, b:BigInt): BigInt =
          if (n == BigInt(0)) a
          else fibTail( n-1, b, a+b )
        fibTail( n, BigInt(0), BigInt(1))
      }
    
    @ for (overflow<-1 to 8) println("10^" + overflow + ": " + fib(BigInt(math.pow(10,overflow).toLong)))
    10^1: 55
    10^2: 354224848179261915075
    10^3: 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
    10^4: 33644764876431783266621612005107543310302148460680063906564769974680081442166662368155595513633734025582065332680836159373734790483865268263040892463056431887354544369559827491606602099884183933864652731300088830269235673613135117579297437854413752130520504347701602264758318906527890855154366159582987279682987510631200575428783453215515103870818298969791613127856265033195487140214287532698187962046936097879900350962302291026368131493195275630227837628441540360584402572114334961180023091208287046088923962328835461505776583271252546093591128203925285393434620904245248929403901706233888991085841065183173360437470737908552631764325733993712871937587746897479926305837065742830161637408969178426378624212835258112820516370298089332099905707920064367426202389783111470054074998459250360633560933883831923386783056136435351892133279732908133732642652633989763922723407882928177953580570993691049175470808931841056146322338217465637321248226383092103297701648054726243842374862411453093812206564914032751086643394517512161526545361333111314042436854805106765843493523836959653428071768775328348234345557366719731392746273629108210679280784718035329131176778924659089938635459327894523777674406192240337638674004021330343297496902028328145933418826817683893072003634795623117103101291953169794607632737589253530772552375943788434504067715555779056450443016640119462580972216729758615026968443146952034614932291105970676243268515992834709891284706740862008587135016260312071903172086094081298321581077282076353186624611278245537208532365305775956430072517744315051539600905168603220349163222640885248852433158051534849622434848299380905070483482449327453732624567755879089187190803662058009594743150052402532709746995318770724376825907419939632265984147498193609285223945039707165443156421328157688908058783183404917434556270520223564846495196112460268313970975069382648706613264507665074611512677522748621598642530711298441182622661057163515069260029861704945425047491378115154139941550671256271197133252763631939606902895650288268608362241082050562430701794976171121233066073310059947366875
    10^5: 259740693472217241661550340212759154148804853865176965847247707039525345435112736862655567728367167447546375872230744321116383994738750910309656973821883044930522876385313349213530267927895670105127657827163560807305053220024323311438398651613782723812477745377833729991621463405005466986039086275099663936640921189012527196017210506030035058689402855810367511765825136837743868493641345733883436515877542537191241050033219599133006220436303521375652542182399869084855637408017925176162939175496345855861630076281991608110983652635299544069428420657104604490380564713634603300052085227770755444679472370903097901901486043284681985796101595100185060826491923458731339915013391993236310230186417253647713626647508013398243123170343145296418179005118795731676683497990168201184990775668645684506628739248560391404760519955006628882634587718941068037009187936500173301171002831047394745625609144493282137485557386408057981302826664027035429441210491999580313187680589918651342517595991152056315533770399694103551827527491995980225750790203779810308992298499630449625581404551700025029976432219346216536621084187674542829826139823447836658158804081900330738293950008213200937471548513102722081730543226486694963098791471436292555425262404399961532697987680751064681906879211829916796440917827186856170291810221267926740136265049978496884368097525470013100457418640644829948587255174474669565187912691699324456481767332225714931496776334584662383033382023970243...
    

    这是意料之中的,因为虽然fib(100)参数 完全在IntLong 的范围内,但返回的 却远远超出了它。

    @ Long.MaxValue
    res14: Long = 9223372036854775807L
    
    @ 354224848179261915075L // fib(10^2)
    (console):1: integer number too large
    354224848179261915075L
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-07
      • 2016-06-01
      • 2012-11-14
      • 1970-01-01
      • 2021-01-26
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多