Float vs integer and the == sign

I noticed that when D has at least one floating numbers, this program will work:
D = [-0, 0, 1, 5, 0, 7.1, 0]
D[D .== 0] .= 0.0001;

But it will quit working when D is composed of integers entirely.
D = [-0, 0, 1, 5, 0, 7, 0]
D[D .== 0] .= 0.0001;

Error message:

InexactError: Int64(0.0001)

Stacktrace:
 [1] Int64
   @ ./float.jl:723 [inlined]
 [2] convert
   @ ./number.jl:7 [inlined]
 [3] fill!(A::SubArray{Int64, 1, Vector{Int64}, Tuple{Vector{Int64}}, false}, x::Float64)
   @ Base ./multidimensional.jl:1055
 [4] copyto!
   @ ./broadcast.jl:944 [inlined]
 [5] materialize!
   @ ./broadcast.jl:894 [inlined]
 [6] materialize!(dest::SubArray{Int64, 1, Vector{Int64}, Tuple{Vector{Int64}}, false}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}, Nothing, typeof(identity), Tuple{Float64}})
   @ Base.Broadcast ./broadcast.jl:891
 [7] top-level scope
   @ In[209]:2
 [8] eval
   @ ./boot.jl:360 [inlined]
 [9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1116

In reality, my D can be all integers or not. What should be the fix? Thanks!

The fix is either

D = [-0.0, 0.0, 1.0, 5.0, 0.0, 7.0, 0.0]

or

D = Float64[-0, 0, 1, 5, 0, 7, 0]
2 Likes

Thanks.

I’m able to apply the below to my data:
convert(Array{Float64}, D)

Much nicer to write

Float64.(D)

But isn’t it better to make D a float array in the first place instead?

1 Like

Much nicer to write

Float64.(D)

Why not use float?

julia> float(D)
7-element Vector{Float64}:
 0.0
 0.0
 1.0
 5.0
 0.0
 7.0
 0.0
3 Likes

Two main comments here.

  1. Array type in Julia is specified at the point of its creation. So if you create an array with all the elements of type Int64, you will get an array{Int64,<dims>}. The array type is fixed at this point and cannot be changed later without allocating a new array. Now when you try to insert the value 0.0001 to replace 0 it must be converted first to an Int64, but 0.0001 cannot be represented as Int64 and this is the error you get. To avoid this, you either have to allocate a new array or simply add at least one Float64 element when creating D, like this D = [-0.0, 0, 1, 5, 0, 7, 0].

  2. The allocation-free functional programming style is usually the recommended way to code in Julia. Instead of the of the MATLAB-ish way that you used, you can write replace!(x -> iszero(x) ? 0.0001 : x, D) which is faster and have zero allocations.

11 Likes

Many thanks!

This is such a nicer solution :+1:

2 Likes

There’s an even simpler version of the solution provided by @Seif_Shebl:

replace!(D, 0 => 0.0001)
5 Likes