Mucking around with numbers

So, I was reading up on the Fibonacci sequence the other day, and wondered how long it would take CF to calculate the sequence to a couple of thousand steps, and also how long those numbers ended up becoming.

Consider the following loop:

<cfset n1 =0>
<cfset n2 =1>
<table>
<thead>
<tr><th>Row</th><th>No.</th><th>Length</th>
</thead>
<tbody>
<cfloop from="1" to="1000" index="i">
<cfset x = (n1 + n2)>
<cfoutput>
<tr><td>#i#</td><td>#len(numberformat(x))#</td><td>#numberformat(x)#</td></tr>
</cfoutput>
<cfset n1 = n2>
<cfset n2 = x>
</cfloop>
</tbody>
</table>

I immediately hit a few issues. One was scientific notation, which was solved by numberformat(), but the other issue I found was that if I tried to increase the number of loop iterations beyond 1475, I’d get an error simply stating ‘For input string: “I”‘

Removing the numberformat mask revealed 1.30698922376E+308 as the largest generated number in the sequence, with the remaining rows represented as ’1.#INF’.

So, out of curiosity, does anyone know why? Is it simply that Java can’t handle larger integers?

Incoming search terms:

  • (2-2-52)·21023
  • java double (2-2-52)·21023
  • Tom K

    Thanks Aaron – interesting stuff…!

  • http://iknowkungfoo.com Adrian J. Moreno

    It’s a representation of Infinity.

    http://rosettacode.org/wiki/Infinity#Java

    In Java, the Max Value for a Double is (2-2-52)*21023. Anything above that is represented as Infinity.

    FWIW, I didn’t get this until

    1477 1.30698922376E+308
    1478 1.#INF

    using CF 8 on 64-bit JVM 1.6.0_24.

  • Aaron DeRenard

    You hit the end of the road for floating point numbers in java.

    CF uses Java’s double precision floating point numbers, which has an upper limit of about 1.7977×10^308 and next comes either infinity or not a number.

    This is less about a limitation of Java and more about a limitation of floating point precision of modern computers. That being said, there are platforms that are better at math than others, and CF runs with a least common denominator selection that is pretty much guaranteed to run on most platforms reliably.

    If you want to go further, consider using an arbitrary precision data type provided by Java like BigInteger. There other libraries like IronPython that you could use, but Java already provides libraries that would be easier to leverage in CF.

    Have fun!

  • http://headsplode.com Travis

    1.30698922376E+308 is just shy of a basic java “double”.

    Anything larger than the basic java data types uses BigInteger and BigDecimal which is actually an object (like a string) but uses its own syntax.

    MyBigInteger1+ MyBigInteger2 is incorrect.
    MyBigInteger1.add(MyBigInteger2) is the correct syntax.
    If you want to add a small number to a BigInteger you’ll need to do something like MyBigInteger1.add(BigInteger.valueOf(mySmallNumber))

    I’ve only used them once when when calculating distances between galaxies using small units like Miles and Kilometers.

    http://download.oracle.com/javase/1.4.2/docs/api/java/math/BigInteger.html

    In order to use BI and BD in CF you’ll need to do something like this:
    http://cfg11n.blogspot.com/2006/02/big-numbers-in-coldfusion.html

    have fun. :)