Clojure

bigint, biginteger throw on double values outside of long range

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: Release 1.6
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test
  • Approval:
    Ok

Description

The bigint and biginteger functions throw on double values outside of long range

This works fine:

user> (bigint (* 0.99 Long/MAX_VALUE))
9131138316486227968N

but passing any Float or Double values outside the range of a long throw an exception:

user> (bigint (* 1.01 Long/MAX_VALUE))
IllegalArgumentException Value out of range for long: 9.315605757223324E18  clojure.lang.RT.longCast (RT.java:1178)

Cause: bigint and biginteger cover a series of possible input cases but did not have an explicit case for Float or Double, so was falling back to default.

Solution: Add check for Float/Double case that coerces the input to double, then uses BigDecimal.valueOf(), then converts to a BigInteger and so on as with other types.

Patch: clj-1197-make-bigint-work-on-all-doubles-v1.txt

Activity

Andy Fingerhut made changes -
Field Original Value New Value
Description This works fine:

{{{
user> (bigint (* 0.99 Long/MAX_VALUE))
9131138316486227968N
}}}

but this and any other Float or Double values outside the range of a
long throw an exception:

{{{
user> (bigint (* 1.01 Long/MAX_VALUE))
IllegalArgumentException Value out of range for long: 9.315605757223324E18 clojure.lang.RT.longCast (RT.java:1178)
}}}

Similarly for biginteger
This works fine:

    user> (bigint (* 0.99 Long/MAX_VALUE))
    9131138316486227968N

but this and any other Float or Double values outside the range of a
long throw an exception:

    user> (bigint (* 1.01 Long/MAX_VALUE))
    IllegalArgumentException Value out of range for long: 9.315605757223324E18 clojure.lang.RT.longCast (RT.java:1178)

Similarly for biginteger
Hide
Andy Fingerhut added a comment -

Patch clj-1197-make-bigint-work-on-all-doubles-v1.txt dated Apr 7 2013 changes bigint and biginteger so that they return the correct value for all float and double values, and no longer throw an exception.

Show
Andy Fingerhut added a comment - Patch clj-1197-make-bigint-work-on-all-doubles-v1.txt dated Apr 7 2013 changes bigint and biginteger so that they return the correct value for all float and double values, and no longer throw an exception.
Andy Fingerhut made changes -
Andy Fingerhut made changes -
Patch Code and Test [ 10002 ]
Hide
Gabriel Horner added a comment -

Looks good. Tests pass and the failing example now converts correctly

Show
Gabriel Horner added a comment - Looks good. Tests pass and the failing example now converts correctly
Gabriel Horner made changes -
Approval Vetted [ 10003 ]
Fix Version/s Release 1.6 [ 10157 ]
Stuart Halloway made changes -
Approval Vetted [ 10003 ] Screened [ 10004 ]
Hide
Alex Miller added a comment -

Cleaned up the description a bit.

Show
Alex Miller added a comment - Cleaned up the description a bit.
Alex Miller made changes -
Description This works fine:

    user> (bigint (* 0.99 Long/MAX_VALUE))
    9131138316486227968N

but this and any other Float or Double values outside the range of a
long throw an exception:

    user> (bigint (* 1.01 Long/MAX_VALUE))
    IllegalArgumentException Value out of range for long: 9.315605757223324E18 clojure.lang.RT.longCast (RT.java:1178)

Similarly for biginteger
The {{bigint}} and {{biginteger}} functions throw on double values outside of long range

This works fine:

{code}
user> (bigint (* 0.99 Long/MAX_VALUE))
9131138316486227968N
{code}

but passing any Float or Double values outside the range of a long throw an exception:

{code}
user> (bigint (* 1.01 Long/MAX_VALUE))
IllegalArgumentException Value out of range for long: 9.315605757223324E18 clojure.lang.RT.longCast (RT.java:1178)
{code}

*Cause:* {{bigint}} and {{biginteger}} cover a series of possible input cases but did not have an explicit case for Float or Double, so was falling back to default.

*Solution:* Add check for Float/Double case that coerces the input to double, then uses BigDecimal.valueOf(), then converts to a BigInteger and so on as with other types.

*Patch:* {{clj-1197-make-bigint-work-on-all-doubles-v1.txt}}
Rich Hickey made changes -
Approval Screened [ 10004 ] Ok [ 10007 ]
Stuart Halloway made changes -
Resolution Completed [ 1 ]
Status Open [ 1 ] Closed [ 6 ]

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: