# Unexpected result about integer

**URL:** <https://discourse.julialang.org/t/unexpected-result-about-integer/13485>\
**Category:** General Usage\
**Created:** [August 15, 2018, 5:48am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485 "2018-08-15T05:48:26Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![yelf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yelf/32/4985_2.png) [@yelf](https://discourse.julialang.org/u/yelf)\
**Post date:** [August 15, 2018, 5:48am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/1 "2018-08-15T05:48:27Z")

</div>

I’m a python user doing scientific computing. I’m also interested in julia, and tried it after v1.0 released.  
I haven’t start learning julia yet, only tried it as a simple calculator, and get some unexpected result.

**Evenviroment** :  
julia Version 1.0.0 (2018-08-08)  
Python 3.6.5 |Anaconda custom (64-bit)  
Ubuntu 18.04

```julia
julia> 10^23*10^-23
2.003764205206899e-6

julia> 10.0^23*10.0^-23
0.9999999999999999

julia> 10^23
200376420520689664

julia> 10.0^23
1.0e23

julia> 10^1000 + 1
1

julia> 10.0^1000 + 1
Inf

julia> 10^1000 + 1.0
1.0

julia> typeof(1)
Int64

julia> typeof(1.0)
Float64

```

The reason is simple: the int64 type of julia has a max value of `2^63-1`.  
I don’t know if this should be considered as a bug, but the result is really unexpected.  
A warning or an error would be much better.  
Tell me some thing went wrong is better than return the misleading result without a warning.

Compare with Python:  
the int type of python seems can be unlimited large.  
the float type has a max value of `1.7976931348623157e+308`.  
When the value is out of range, it will return a OverflowError.

```python
>>> 10 **23*10** -23
0.9999999999999999

>>> 10.0 **23*10.0** -23
0.9999999999999999

>>> 10**23
100000000000000000000000

>>> 10.0**23
1e+23

>>> 10**1000 + 1
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

>>> 10.0**1000 + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')

>>> 10**1000 + 1.0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float

>>> type(1)
<class 'int'>

>>> type(1.0)
<class 'float'>

>>> import sys
>>> sys.float_info.max
1.7976931348623157e+308

```

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [August 15, 2018, 6:13am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/2 "2018-08-15T06:13:30Z")

</div>

A couple of remarks:

- Julia is rather explicit about the nature of number types so with an `Int64` you get what you expect (Integer type backed by 64bits).
- There is a `BigInt` and `BigFloat` type for arbitrary precision. (eg. `BigInt(3)^BigInt(220)`)
- Julia devs have decided to default to overflow for the sake of performance ([https://docs.julialang.org/en/stable/manual/integers-and-floating-point-numbers/#Overflow-behavior-1](https://docs.julialang.org/en/stable/manual/integers-and-floating-point-numbers/#Overflow-behavior-1))
- If you want to handle overflow you’ll have to use something like: [https://github.com/JeffreySarnoff/SaferIntegers.jl](https://github.com/JeffreySarnoff/SaferIntegers.jl)

---

<div class="post-metadata">

**Author:** ![yelf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yelf/32/4985_2.png) [@yelf](https://discourse.julialang.org/u/yelf)\
**Post date:** [August 15, 2018, 8:10am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/3 "2018-08-15T08:10:52Z")

</div>

```julia
julia> BigInt(10^1000) + 1
1

julia> BigFloat(10.0^1000) + 1
Inf

julia> BigInt(10)^BigInt(1000) + 1
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

julia> BigFloat(10.0)^BigInt(1000) + 1
1.000000000000000000000000000000000000000000000000000000000000000000000000000004e+1000

julia> BigInt(10)^BigInt(23)*BigInt(10)^BigInt(-23)
ERROR: DomainError with -23:
`y` cannot be negative.
Stacktrace:
 [1] bigint_pow(::BigInt, ::BigInt) at ./gmp.jl:504
 [2] ^(::BigInt, ::BigInt) at ./gmp.jl:525
 [3] top-level scope at none:0

julia> BigInt(10)^BigInt(23)*BigInt(10)^-BigInt(23)
ERROR: DomainError with -23:
`y` cannot be negative.
Stacktrace:
 [1] bigint_pow(::BigInt, ::BigInt) at ./gmp.jl:504
 [2] ^(::BigInt, ::BigInt) at ./gmp.jl:525
 [3] top-level scope at none:0

julia> BigInt(10)^BigInt(23)*BigInt(10)^BigFloat(-23)
1.0

```

I need to put every single number in `BigInt()` or `BigFloat()` to get the right ans.  
With `SaferIntegers.jl`, I also need to put every single number in `SafeInt()`.  
This seems kinda silly to me.

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [August 15, 2018, 9:31am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/4 "2018-08-15T09:31:30Z")

</div>

Not necessarily every number:

```julia
julia> 10^BigInt(23)*10^BigFloat(-23)
1.0
julia> SafeInt8(127) * 2
ERROR: OverflowError: 127 * 2 overflowed for type Int8

```

And I wouldn’t say that the explicitness is silly. In the worst case you can call it inconvenient but only if you are using Julia not as a programming language but as a glorified calculator in which you have to enter a myriad of number literals.

A nice blog post which might help you understand the default: [Computers are Machines · John Myles White](http://www.johnmyleswhite.com/notebook/2013/01/03/computers-are-machines/)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 15, 2018, 11:09am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/5 "2018-08-15T11:09:19Z")

</div>

I think this is a bit more convenient, and it is also faster:

```julia
big(10)^23 * big(10)^-23

```

or

```julia
b = big(10)
b^23 * b^-23

```

Compare:

```julia
julia> @btime 10^big(23)
  341.462 ns (7 allocations: 152 bytes)
100000000000000000000000

julia> @btime big(10)^23
  263.409 ns (5 allocations: 112 bytes)
100000000000000000000000

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 15, 2018, 11:14am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/6 "2018-08-15T11:14:47Z")

</div>

But, oops, it is less accurate. Hmmm:

```julia
julia> big(10)^23 * big(10)^-23
1.000000000000000000000000000000000000000000000000000000000000000000000000000052

julia> 10^BigInt(23)*10^BigFloat(-23)
1.0

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 15, 2018, 11:22am UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/7 "2018-08-15T11:22:26Z")

</div>

Actually, there is some weirdness going on here:

```julia
julia> big(10)^(-24)
1.000000000000000000000000000000000000000000000000000000000000000000000000000057e-24

julia> expo = -24
-24

julia> big(10)^expo
ERROR: DomainError with -24:
`y` cannot be negative.
Stacktrace:
 [1] bigint_pow(::BigInt, ::Int64) at ./gmp.jl:504
 [2] ^(::BigInt, ::Int64) at ./gmp.jl:527
 [3] top-level scope at none:0

```

It must have something to do with that literals are handled differently from variables, but that one was a surprise to me.

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [August 15, 2018, 12:03pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/8 "2018-08-15T12:03:30Z")

</div>

You are right, this looks weird. It appears to be a regression introduced in 0.7.

```julia
julia> VERSION
v"0.6.4"

julia> big(10)^(-23)
ERROR: DomainError:
Stacktrace:
 [1] bigint_pow(::BigInt, ::Int64) at ./gmp.jl:461
 [2] literal_pow(::Base.#^, ::BigInt, ::Type{Val{-23}}) at ./intfuncs.jl:208

julia> expo = -23
-23

julia> big(10)^expo
ERROR: DomainError:
Stacktrace:
 [1] bigint_pow(::BigInt, ::Int64) at ./gmp.jl:461
 [2] ^(::BigInt, ::Int64) at ./gmp.jl:482

```

vs.

```julia
julia> VERSION
v"0.7.0"

julia> big(10)^(-23)
1.000000000000000000000000000000000000000000000000000000000000000000000000000045e-23

julia> expo = -23
-23

julia> big(10)^expo
ERROR: DomainError with -23:
`y` cannot be negative.
Stacktrace:
 [1] bigint_pow(::BigInt, ::Int64) at ./gmp.jl:504
 [2] ^(::BigInt, ::Int64) at ./gmp.jl:527
 [3] top-level scope at none:0

```

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [August 15, 2018, 12:42pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/9 "2018-08-15T12:42:24Z")

</div>

> [@laborg](#):
>
> 10^BigInt(23)\*10^BigFloat(-23)

You could also write (see decimal point in second exponent to force BigFloat):

```julia
10^big"23"*10^big"-23."

```

> [@yelf](#):
>
> I need to put every single number in `BigInt()` or `BigFloat()` to get the right ans.  
> With `SaferIntegers.jl` , I also need to put every single number in `SafeInt()` .  
> This seems kinda silly to me.

I agree. But we could probably create some macros similar to this:

```julia
> using MacroTools: postwalk
> macro bf(a) postwalk(x -> x isa Integer ? BigFloat(x) : x, a) end;
> macro bi(a) postwalk(x -> x isa Integer ? BigInt(x) : x, a) end;

> @bf 10^23 * 10^-23
1.0

> @bi begin 
              println(10^100 + 1)
              println(10^1000 + 1 - 10^1000 - 1)
      end
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
0

```

Be aware that simply convert to BigFloat isn’t “safe”:

```julia
> @bf 10^1000 + 1 - 10^1000 - 1
-1.0

```

---

<div class="post-metadata">

**Author:** ![yelf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yelf/32/4985_2.png) [@yelf](https://discourse.julialang.org/u/yelf)\
**Post date:** [August 15, 2018, 2:58pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/10 "2018-08-15T14:58:28Z")

</div>

```julia
julia> 10^1000
0

julia> 10^BigInt(1000)
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

julia> 10^BigFloat(1000)
1.000000000000000000000000000000000000000000000000000000000000000000000000000004e+1000

julia> 10^BigInt(1000) + 1 - 10^BigInt(1000) - 1
0

julia> 10^BigFloat(1000) + 1 - 10^BigFloat(1000) - 1
-1.0

```

So, even with `BigInt/BigFloat()` I may still get wrong ans without being aware of it.  
And Python has the same problem. #TIL 👍

```python
>>> 10 **1000 + 1 - 10** 1000 - 1
0

>>> 10. **1000 + 1 - 10.** 1000 - 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')

>>> 10 **100 + 1 - 10** 100 - 1
0

>>> 10.0 **100 + 1 - 10.0** 100 - 1
-1.0

```

* * *

But what’s going on here:

```julia
julia> 10^BigInt(100) + 1 - 10^BigInt(100) - 1.0
0.0

julia> 10^BigInt(100) + 1.0 - 10^BigInt(100) - 1
-1.0

julia> 10^BigInt(110) + 1.0 - 10^BigInt(110) - 1
-1.0

julia> 10^BigInt(111) + 1.0 - 10^BigInt(111) - 1
-2.596148429267413814265248164610049e+33

julia> 10^BigInt(308) + 1.0 - 10^BigInt(308) - 1
-4.278797250636008849512039341305132266417330874820046369744080218757492603003989e+230

julia> 10^BigInt(309) + 1.0 - 10^BigInt(309) - 1
5.036311303168244761381837589469883065123985227880133297090232009398813113114232e+231

julia> 10^BigInt(1000) + 1.0 - 10^BigInt(1000) - 1
4.357748021848539487284672161416420590604097564749035815958799690306706944059397e+922

```

v.s. Python

```python
>>> 10 **100 + 1 - 10** 100 - 1.0
0.0

>>> 10 **100 + 1.0 - 10** 100 - 1
-1.0

>>> 10 **110 + 1.0 - 10** 110 - 1
-1.0

>>> 10 **111 + 1.0 - 10** 111 - 1
-1.0

>>> 10 **308 + 1.0 - 10** 308 - 1
-1.0

>>> 10 **309 + 1.0 - 10** 309 - 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float

>>> 10 **1000 + 1.0 - 10** 1000 - 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float

```

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [August 15, 2018, 4:53pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/11 "2018-08-15T16:53:25Z")

</div>

> [@yelf](#):
>
> So, even with `BigInt/BigFloat()` I may still get wrong ans without being aware of it.  
> And Python has the same problem. #TIL 👍

You are using BigFloat which has limited precision:  
10^BigFloat(1000) and 10^BigFloat(1000)+1 are the same BigFloat number so  
(10^BigFloat(1000) + 1 ) - 10^BigFloat(1000) is zero,  
then  
((10^BigFloat(1000) + 1 ) - 10^BigFloat(1000)) - 1 is -1

You would need 1000 decimals of precision for this computation:

```julia
julia> log2(10^BigFloat(1000))
3.32192809486e+03

julia> setprecision(3322)
3322

julia> 10^BigFloat(1000) + 1 - 10^BigFloat(1000) - 1
0.0

```

Edit: also python does not have a native big float type, so it will fail to convert a large integer to a float, whereas julia converts BigInt to BigFloat which explains the python error.

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [August 15, 2018, 5:05pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/12 "2018-08-15T17:05:37Z")

</div>

> [@yelf](#):
>
> But what’s going on here:
> 
> ```julia
> julia> 10^BigInt(100) + 1 - 10^BigInt(100) - 1.0
> 0.0
> 
> julia> 10^BigInt(100) + 1.0 - 10^BigInt(100) - 1
> -1.0
> 
> julia> 10^BigInt(110) + 1.0 - 10^BigInt(110) - 1
> -1.0
> 
> julia> 10^BigInt(111) + 1.0 - 10^BigInt(111) - 1
> -2.596148429267413814265248164610049e+33
> 
> julia> 10^BigInt(308) + 1.0 - 10^BigInt(308) - 1
> -4.278797250636008849512039341305132266417330874820046369744080218757492603003989e+230
> 
> julia> 10^BigInt(309) + 1.0 - 10^BigInt(309) - 1
> 5.036311303168244761381837589469883065123985227880133297090232009398813113114232e+231
> 
> julia> 10^BigInt(1000) + 1.0 - 10^BigInt(1000) - 1
> 4.357748021848539487284672161416420590604097564749035815958799690306706944059397e+922
> 
> ```

Those errors are within the default precision of BigFloat, this will go away if you use larger precision.

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [August 17, 2018, 4:19pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/13 "2018-08-17T16:19:37Z")

</div>

> [@yelf](#):
>
> But what’s going on here:
> 
> ```julia
> julia> 10^BigInt(100) + 1 - 10^BigInt(100) - 1.0
> 0.0
> 
> julia> 10^BigInt(100) + 1.0 - 10^BigInt(100) - 1
> -1.0
> 
> julia> 10^BigInt(110) + 1.0 - 10^BigInt(110) - 1
> -1.0
> 
> julia> 10^BigInt(111) + 1.0 - 10^BigInt(111) - 1
> -2.596148429267413814265248164610049e+33
> 
> julia> 10^BigInt(308) + 1.0 - 10^BigInt(308) - 1
> -4.278797250636008849512039341305132266417330874820046369744080218757492603003989e+230
> 
> julia> 10^BigInt(309) + 1.0 - 10^BigInt(309) - 1
> 5.036311303168244761381837589469883065123985227880133297090232009398813113114232e+231
> 
> julia> 10^BigInt(1000) + 1.0 - 10^BigInt(1000) - 1
> 4.357748021848539487284672161416420590604097564749035815958799690306706944059397e+922
> 
> ```

I am still trying to figure this one out. Even though they are within the default relative precision of BigFloat which you can check with the eps method:

```julia
julia> eps(big"1e111")
1.0384593717069655257060992658440192e+34

julia> eps(big"1e308")
1.552518092300708935148979488462502555256886017116696611139052038026050952686377e+231

julia> eps(big"1e309")
1.242014473840567148119183590770002044205508813693357288911241630420840762149102e+232

julia> eps(big"1e1000")
9.077509367765559473217972708288397454198398713067023807283572112948755829682985e+922

```

I would still expect from the order of operations and promotions to get -1 for all of them.  
What is going on here:

```julia
julia> BigFloat(10^BigInt(309))-(10^BigInt(309))
5.036311303168244761381837589469883065123985227880133297090232009398813113114232e+231

julia> typeof(10^BigInt(309))
BigInt

julia> promote_type(BigFloat,BigInt)
BigFloat

```

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [August 17, 2018, 4:33pm UTC](https://discourse.julialang.org/t/unexpected-result-about-integer/13485/14 "2018-08-17T16:33:01Z")

</div>

```julia
julia> a=BigFloat(10^BigInt(309))
1.000000000000000000000000000000000000000000000000000000000000000000000000000005e+309

julia> b=10^BigInt(309)
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

julia> @which a+b
+(x::BigFloat, c::BigInt) in Base.MPFR at mpfr.jl:349

```

It is using a MPFR method (most specific dispatch) to operate on mixed types and not going through promotions, so this explains the observations. As long as it is within the expected precision this is good but it was surprising to me.
