# Interval times Int64 and Interval times BigInt discrepancy

**URL:** https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902
**Category:** General Usage
**Tags:** bug, intervals
**Created:** [December 15, 2020, 11:30pm UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902 "2020-12-15T23:30:16Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [December 15, 2020, 11:30pm UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/1 "2020-12-15T23:30:16Z")

</div>

I want to get the positive root of some polynomials with ridiculous precision. The polynomials I care I about are of the form \sum\_{k=0}^{n-1} a\_k x^k - x^n, with a\_k's being natural numbers. I am trying to write a program that does that efficiently and I found a weird bug.

The following is a minimal example. Unfortunately, I couldn’t minimise it any more.

```julia
using IntervalArithmetic

struct CauchyPolynomial{T,S,I<:Union{Int,Int128,BigInt}}
    c::NTuple{T,I}
    d::NTuple{S,I}
end

function CauchyPolynomial(ar::NTuple{N,T}) where N where T <:Union{Int,Int128,BigInt}
    d = zeros(T,length(ar)-1)
    for i in 2:length(ar)
        d[i-1] = (i-1)*ar[i]
    end
    CauchyPolynomial(ar, tuple(d...))
end

@generated function pval_g(c::NTuple{N,I}, x::R) where I<:Union{Int,Int128,BigInt} where R<:Real where N
    r = :(-one(R))
    for i in N:-1:1
        r = :(muladd(x, $r, c[$i] ) )
    end
    return r
end

@generated function dval_g(d::NTuple{N,I}, x::R) where I<:Union{Int,Int128,BigInt} where R<:Real where N
    r = :(-one(R)*(N+1))
    for i in N:-1:1
        r = :(muladd(x, $r, d[$i] ) )
    end
    return r
end

function pval(p::CauchyPolynomial{M,N}, x::R) where M where N where R<:Real
    return pval_g(p.c, x)
end

function dval(p::CauchyPolynomial{M,N}, x::R) where M where N where R<:Real
    return dval_g(p.d, x)
end

function root(p::CauchyPolynomial{M,N}, bts::Int) where M where N
    println("root called: ",p," - ",bts)
    m = max(p.c...)
    x = @biginterval m
    while -log2(diam(x)) > bts
        for i in 1:100
            pt = pval(p,x)
            x = x - pt/dval(p,x)
            if 0 in pt
                return x
            end
        end
    end
    throw(ErrorException("Newton method timed out, p: "*string(p)))
end

setprecision(8384);

ts = (832152526037543613, 4191427560420539572, 1948805851146604192, 41780545826284041, 2952882476324826786);
tb = map(big, ts);

ps = CauchyPolynomial(ts);
pb = CauchyPolynomial(tb);

root(pb, 8303)
root(ps, 8303)

```

When I execute this, the line `root(pb, 8303)` gives me the root but the line `root(ps, 8303)` times out.

The only difference between the polynomials `ps` and `pb` is that the coefficients of `ps` are `Int64` and the ones of `pb` are `BigInt`. Since integers are represented exactly, I expected that the difference in types wouldn’t matter. What is happening here?

Also, separate to this issue, any advice on how to improve the code is more than welcomed.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [December 15, 2020, 11:54pm UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/2 "2020-12-15T23:54:34Z")

</div>

For relatively short polynomials, the best way to evaluate this will almost certainly be  
`pval_g(c,x) = evalpoly(x, tuple(c... ,-1))`.  
That said, `BigInt` will always be way slower since `Int` is doing the computation modulo `2^64`.

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [December 16, 2020, 12:27am UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/3 "2020-12-16T00:27:41Z")

</div>

I think my function is faster since it is a generated function that takes into account that the highest order coefficient is always -1. If it is not, then I’m very curious to see why it is not.

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 16, 2020, 12:37am UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/4 "2020-12-16T00:37:54Z")

</div>

(without looking at your code)  
Ints (the default Integer type) are bounded by `(typemin(Int), typemax(Int))` and they will wrap around:

```julia
julia> 0 > typemax(Int) + 2
true

```

So your evaluation logic may be causing the root finder to bounce back and forth ad infinitum when Ints are used with your specific calculation.

BigInts grow and grow, allowing the root finder to utilize whatever integer precision is required in this case.

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [December 16, 2020, 12:46am UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/5 "2020-12-16T00:46:30Z")

</div>

The “point” to be evaluated is `Interval{BigFloat}`. So the result of any computation is also `Interval{BigFloat}`.

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [December 16, 2020, 6:14am UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/6 "2020-12-16T06:14:49Z")

</div>

There was a recent thread about special methods to find roots of polynomials with integer coefficients.

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [December 16, 2020, 12:39pm UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/7 "2020-12-16T12:39:28Z")

</div>

I have seen the that thread, but it was not very useful to me.

Regardless, the integer type should not affect the result of the product. Am I missing something here? Is this not a bug?

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [December 16, 2020, 1:47pm UTC](https://discourse.julialang.org/t/interval-times-int64-and-interval-times-bigint-discrepancy/51902/8 "2020-12-16T13:47:22Z")

</div>

I was an idiot, it overflows when I compute the coefficients of the derivative. 🤦‍♂️
