Joe Bogner wrote:
> J doesn't apparently like numbers that big or
> I need to do something different to enable them
>
> 9223372036854775807^1000000
> _
>
> Looks like it stops around to the 16th power
> 9223372036854775807^16
> 2.74306e303
That exponent of 303 is a hint. IEEE double-precision floating-point
numbers (the 80-bit kind) top out just over 10^308 . The number
9223372036854775807 has 18 digits, and its 16th power has ~303. So its
17th power has ~322 digits, which is larger than the largest floating
point number [1].
While J will transparently promote integers to floating point when needed,
i won't automatically promote floating-point to "big int". When a
floating point operation overflows, J returns _ (infinity). However, J
does support "big ints"*, and you can create them by converting your
numbers with x: as in
x: 1 2 3
1 2 3
datatype 1 2 3
integer
datatype x:1 2 3
extended
or, in numeric constants, by tacking an "x" onto the value, as in [2]:
1 2 3x
1 2 3
datatype 1 2 3
integer
datatype 1 2 3x
extended
Big integer format will carry through calculations, even when mixed with
non-bigint values, so long as the calculations & intermediate values stay
in the integer domain. Non-integral results or intermediate values will
either produce rationals (pairs of bigints representing real numbers) or
fall back to floating point, or, in certain cases, produce nonce errors
[3].
So the following sentences represent several ways you could calculate
9223372036854775807^17 to full precision:
9223372036854775807 ^ 17x
9223372036854775807x ^ 17
9223372036854775807x ^ 17x
9223372036854775807 ^ x:17
(x:9223372036854775807) ^ 17
9223372036854775807 ^&x:17 NB. & means "apply to both arguments
first"
^/9223372036854775807 17x NB. x on last number converts whole
array
^/9223372036854775807 , 17x NB. append promotes "lower" types to
"higher" types
But, of course, this _won't_ work:
x: 9223372036854775807 ^ 17
_
Here, all we've done is convert a floating-point infinity (the result of ^)
to an bigint infinity. We must coerce values to bigint /before/ overflow
occurs. For the sake of completeness, here's a taste of rational numbers
(which, as I said, are represented by pairs of bigints under the covers):
22%7
3.14286
22 % 7x
22r7
22r7
22r7
x:^:_1 ] 22r7 NB. Rational back to floating point
3.14286
_1 x: 22r7 NB. More convenient
3.14286
-Dan
PS: So what's highest power of 9223372036854775807 we can calculate
without getting overflow? Well, the highest IEEE double-precision float
(which J uses internally) is just shy of 2^1024 . Represented in base-10,
it is exactly 1.7976931348623158079990e308 :
1.7976931348623158079990e308 % 9223372036854775807^16
65536
So the highest power possible is just slightly more than 16.25 :
9223372036854775807^ 16+ 1%4
1.51167e308
9223372036854775807^ 16+ 0.25396825396825487009509
1.79769e308
While playing with this, I noticed that 1.79769e308 is so large that it
tends to swallow anything added to it, returning itself (which is
reasonable; you could add a googol to the number and not notice a change
for 200 decimal places). So I wondered what the largest number you could
add to it was without causing overflow:
1.7976931348623158079990e308+9.97920154767359850479990e291
1.79769e308
Incrementing the last digit of either mantissa will overflow the sum and
return _ (trying to increase the numbers by adding trailing 9s will have
no effect; these digits already carry the maximum precision [22 digits]).
[1] The J community uses the term "extended precision integers" for
bigints,
somewhat at odds with the rest of the programming world, where
"extended precision" means a kind of floating point number.
[2] There are a couple gotchas with the notation for extended precision
constants.
First, the trailing x conflicts with meaning of x when used in radix
notation (i.e. the digit meaning 33, as in 16b1a2b3c9x). Second, We
also use x to represent Euler's number in exponential notation, as in
1x1,
and sometimes the interpreter gets confused about whether you mean
extended precision or exponential numbers (e.g. 1x1 1x an
"ill-formed number") .
http://www.jsoftware.com/pipermail/general/2004-April/016876.html
[2] There are some corner cases where extended-precision calculations must
fall back to floating point. You can generally mitigate the risk of
that by using the special forms <.@f or >.@f where f . See §II.G for
more details:
http://www.jsoftware.com/help/dictionary/dictg.htm
There are also cases where even floating point would give misleading
results, so instead J produces nonce errors:
http://www.jsoftware.com/pipermail/general/2005-November/025859.html
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm