# Strange bug when truncating BigFloat to UInt8

**URL:** <https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301>\
**Category:** Numerics\
**Tags:** bug\
**Created:** [October 25, 2019, 1:05pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301 "2019-10-25T13:05:37Z")\
**Posts on this page:** 12\
**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:** [October 25, 2019, 1:05pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/1 "2019-10-25T13:05:37Z")

</div>

I am playing a bit with ridiculously big floating point numbers. The following:

```julia
setprecision(8640)

tf = BigFloat(255.11254081778609618826079023493869737962406296545795414517402744704859236140966993143901247046399018605810385229965382224661237237575734540437335370703455101999206434545185652629184342277273809652057173822177535225305169126047961225905508911234185717183743412115200362744894452638970477737566761804028973656927947961862252399541005064976989957545097283625458545512979419419583797514355530824965946083791230028370659489543325462848471362878871531484111771705355370421927291420333769038750965298417800232034805529408061970430135945167766487117170521878186919447606566027745194654377620946145571463604191062057351380190187814870206558909339930024362284560068075769140591856545226007081662383644602389241138632681859686333475654445711994432287161483584642369129765968240018213994716082457344853966797231896348610241546631043535859686756321457284751256086493098862641443858657732581904367195064136501248686643155681279523637299264337783176675396282349504057481698365127663691328899843083225168295969140945633899140964447581239378570797779065826452960758865545939538343404231764422728125818189151076049211759296760897091244735300051423016481098776865512795849977793724965232640460837614245302532492181948719466289970850591632566536134417436318112170859681583333347677160716550527688519599117467062956658812723853289220649136533890537037382896935150138858174206598983271127954064826589338132762912345445855812435520698519879706990589284804017949221992383032754967592504288236010793141827486018147664332825577383438883762724885174207161136882482051998632049044726801257826671978124551852765579167015665773887434392739407031097566831766910765737452829146516243009566328872494671237672962683589385643979094081890464618960154722506169086232468547493552740608612054650768481200391871274313900835204067203524998278788704495062180165125977886128659711956728963862285943077913267931066408662407024257325491518590542379611319583166005779326374299358877528996142167877032390325791826547992399385695290780413507436459751195530697434346107776989785267608149700794090523161417993259100848857216424097582530060801583603897876587777471027634127970796763578516877161490318688249623106665859063291828603118117172361254632116055644541517117743255060400298516722941278131561059281745861575876971661968930101853829232150678662073133619513917280841190069934015199616973203703361765264061308960725804943132237004823409760989946480764708631512464)

trunc(UInt8,tf)

```

Throws an inexact error! If I truncated first to `Int64` and then convert it to `UInt8` it works fine. I have no clue what is happening here.

I am using widows (Julia 1.2.0) so it may be a bug of the MPFR library.

---

<div class="post-metadata">

**Author:** ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)\
**Post date:** [October 25, 2019, 1:16pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/2 "2019-10-25T13:16:42Z")

</div>

Looks buggy to me (also Windows, Julia 1.2.0:

```julia
julia> trunc(tf)
255.0

julia> trunc(UInt8, tf)
ERROR: InexactError: trunc(UInt8, 255.112540817786083380269701592624187469482421875)
Stacktrace:
 [1] trunc(::Type{UInt8}, ::BigFloat) at .\mpfr.jl:300
 [2] top-level scope at none:0

julia> trunc(UInt8, 255.113)
0xff

julia>

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 1:17pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/3 "2019-10-25T13:17:26Z")

</div>

There seems to be something wrong:

```julia
julia> trunc(Int8,255.0)
ERROR: InexactError: trunc(Int8, 255.0)
Stacktrace:
 [1] trunc(::Type{Int8}, ::Float64) at .\float.jl:675
 [2] top-level scope at REPL[18]:1

```

**as expected.**  
And

```julia
julia> trunc(UInt8,255.0)
0xff

```

**also expected.**  
(ninjad by klaff)

And

```julia
julia> trunc(UInt8,BigFloat(255.0))
0xff

```

**but**

```julia
julia> trunc(UInt8,BigFloat(255.1))
ERROR: InexactError: trunc(UInt8, 255.099999999999994315658113919198513031005859375)
Stacktrace:
 [1] trunc(::Type{UInt8}, ::BigFloat) at .\mpfr.jl:300
 [2] top-level scope at REPL[32]:1

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 1:36pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/5 "2019-10-25T13:36:48Z")

</div>

The relevant code in mpfr.jl is:

```julia
function trunc(::Type{T}, x::BigFloat) where T<:Union{Signed,Unsigned}
    (typemin(T) <= x <= typemax(T)) || throw(InexactError(:trunc, T, x))
    unsafe_cast(T, x, RoundToZero)
end

```

```julia
julia> x = BigFloat(255.1)
255.099999999999994315658113919198513031005859375

julia> T=UInt8
UInt8

julia> (typemin(T) <= x <= typemax(T))
false

```

This explains the InexactError.

But how should it be done? Will have a look into implementation of trunc(Int,Float64)…

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 1:49pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/6 "2019-10-25T13:49:07Z")

</div>

The corresponding check in float.jl , line 672 (Julia 1.3.dev):

```julia
julia> Float64(typemin(UInt8))-one(Float64) < 255.1 < Float64(typemax(UInt8))+one(Float64)
true

```

And therefore:

```julia
julia> trunc(UInt8,255.1)
0xff

```

As it should be.

---

<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:** [October 25, 2019, 1:55pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/7 "2019-10-25T13:55:16Z")

</div>

I guess the same can be done with `BigFloat`, right?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 1:55pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/8 "2019-10-25T13:55:24Z")

</div>

So, the check in mpfr.jl, line 300, should be (perhaps):

```julia
function trunc(::Type{T}, x::BigFloat) where T<:Union{Signed,Unsigned}
    ( BigFloat(typemin(T)-one(BigFloat)) < x < BigFloat(typemax(T)+one(BigFloat)) ) || throw(InexactError(:trunc, T, x))
    unsafe_cast(T, x, RoundToZero)
end

```

OP, want to open an issue?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 1:56pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/9 "2019-10-25T13:56:29Z")

</div>

```julia
removed

```

This above was just wrong.

---

<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:** [October 25, 2019, 1:57pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/10 "2019-10-25T13:57:08Z")

</div>

Sure, I’ll do

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 2:10pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/11 "2019-10-25T14:10:40Z")

</div>

How can I overwrite function

```julia
function trunc(::Type{T}, x::BigFloat) where T<:Union{Signed,Unsigned}
    (typemin(T) <= x <= typemax(T)) || throw(InexactError(:trunc, T, x))
    unsafe_cast(T, x, RoundToZero)
end

```

of mpfr.jl

This seems to be wrong:

```julia
julia> bf=BigFloat(255.1)
255.099999999999994315658113919198513031005859375

julia> import Base.MPFR.trunc

julia> function trunc(::Type{T}, x::BigFloat) where T<:Union{Signed,Unsigned}
                  ( BigFloat(typemin(T)-one(BigFloat)) < x < BigFloat(typemax(T)+one(BigFloat)) ) || throw(InexactError(:trunc, T, x))
                  unsafe_cast(T, x, RoundToZero)
                  end
trunc (generic function with 56 methods)

julia> trunc(UInt8,bf)
ERROR: UndefVarError: unsafe_cast not defined
Stacktrace:
 [1] trunc(::Type{UInt8}, ::BigFloat) at .\REPL[6]:3
 [2] top-level scope at REPL[7]:1

```

unsafe\_trunc is defined:

```julia
julia> Base.MPFR.unsafe_cast(UInt8,bf,RoundToZero)
0xff

```

What am I missing?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 25, 2019, 2:12pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/12 "2019-10-25T14:12:37Z")

</div>

Found the solution:  
Just import unsafe\_trunc too:

```julia
julia> import Base.MPFR.unsafe_cast

julia> trunc(UInt8,bf)
0xff

```

Well, it was nice to talk to me 🙂

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 25, 2019, 3:11pm UTC](https://discourse.julialang.org/t/strange-bug-when-truncating-bigfloat-to-uint8/30301/13 "2019-10-25T15:11:18Z")

</div>

I think it should probably be:

```julia
function trunc(::Type{T}, x::BigFloat) where T<:Union{Signed,Unsigned}
    (typemin(T) < x+1 && x-1 < typemax(T)) || throw(InexactError(:trunc, T, x))
    unsafe_cast(T, x, RoundToZero)
end

```

I would be an easy first PR for someone to submit this patch and add couple of tests

```julia
@test trunc(UInt8, big(-0.3)) === 0x00
@test trunc(UInt8, big(255.1)) === 0xff

```
