Types

This notebook provides (a) a brief introduction to types (for instance, integers, bools and strings), (b) how to test types and (c) convert from one type to another.

Load Packages and Extra Functions


In [1]:
using Dates

include("printmat.jl")


Out[1]:
printyellow (generic function with 1 method)

Some Important Types

Julia has many different types of variables: signed integers (like 2 or -5), floating point numbers (2.0 and -5.1), bools (false/true), bitarrays (similar to bools, but with more efficient use of memory), strings ("hello"), Dates (2017-04-23) and many more.

The numerical types also comes with subtypes for different precisions, for instance, Float16, Float32 and Float64. Unless you specify otherwise, code like

a = 2
b = 2.0

gives an Int64 and a Float64 respectively (at least on the 64 bit version of Julia).

Integers and Floats


In [2]:
a = 2                   #integer, Int (Int64 on most machines)
b = 2.0                 #floating point, (Float64 on most machines)
A = [1;2]
B = [1.0;2.0]

println("a: ",typeof(a))
println(a)

println("\nb: ",typeof(b))
println(b)

println("\nA: ",typeof(A))
printmat(A)

println("B: ",typeof(B))
printmat(B)


a: Int64
2

b: Float64
2.0

A: Array{Int64,1}
         1
         2

B: Array{Float64,1}
     1.000
     2.000

Why Use Int When There Are Floats?

That is, why bother with sometimes using 3 when you could use 3.0 everywhere? Mostly because you cannot use 3.0 everywhere...

For instance, you cannot pick out element x[3.0] from a vector. It has to be x[3].


In [3]:
x = [1,10,100,1000]

#println(x[3.0])    #uncomment and run. Will give an error

println(x[3])


100

Bools and BitArrays


In [4]:
c = 2 > 1.1
println("c: ",typeof(c))
println(c)

C = A .> 1.5
println("\nC: ",typeof(C))
printmat(C)

println("A BitArray is a more economical array version of Bool, but prints as 0/1 by printmat.\n", 
        "Notice that typeof(C[1]) gives: ",typeof(C[1]))


c: Bool
true

C: BitArray{1}
         0
         1

A BitArray is a more economical array version of Bool, but prints as 0/1 by printmat.
Notice that typeof(C[1]) gives: Bool

Char and Strings


In [5]:
t = 'a'                                    #Char, just one letter
println(typeof(t))

txt = "Dogs are nicer than cats."          #String, could be a long novel 
println(typeof(txt))


Char
String

Calculations with Mixed Types and Converting Types

A calculation like "integer" + "float" works and the type of the result is a float (the more flexible type). Similarly, "bool" + "integer" will give an integer.

There are also direct ways of converting a variable from one type to another using the convert() function.

Some Calculations with Mixed Types ("promotion")


In [6]:
println("Int + Float64: ",1+2.0)             
println("Bool + Int: ",(1 .> 0) + 2)


Int + Float64: 3.0
Bool + Int: 3

Converting from Int to Float and Vice Versa


In [7]:
x = [1.1;10.1;100.1]
println("x: ",typeof(x))
printmat(x)

B_to_Int = round.(Int,x)                     #Float64 -> Int by rounding
println("rounding x to Int: ",typeof(B_to_Int))
printmat(B_to_Int)

A = [1;2]
println("A: ",typeof(A))
printmat(A)

A_to_Float64 = convert.(Float64,A)            #Int -> Float64
println("after converting A to Float64: ",typeof(A_to_Float64))   
printmat(A_to_Float64)                        #Float64.(A) also works


x: Array{Float64,1}
     1.100
    10.100
   100.100

rounding x to Int: Array{Int64,1}
         1
        10
       100

A: Array{Int64,1}
         1
         2

after converting A to Float64: Array{Float64,1}
     1.000
     2.000

Converting from Bools and BitArrays to Int and Vice Versa


In [8]:
C = A .> 1.5
C_to_Int = convert.(Int,C)               #BitArray -> Int
println(typeof(C_to_Int))                #Int.(C) also works
printmat(C_to_Int)

D = [1;0;1]
D_to_Bool = convert.(Bool,D)              #Int -> BitArray
println(typeof(D_to_Bool))                #Bool.(D) also works 
printmat(D_to_Bool)


Array{Int64,1}
         0
         1

BitArray{1}
         1
         0
         1

From Bools and BitArrays to Int: A Tricky Case (extra)

false is a "strong zero" in the sense that false*NaN == 0 and false*Inf == 0.

If you do not want that behaviour in your code, transform false to 0 and then multiply.


In [9]:
println(false*NaN)
println(false*Inf)

println(convert(Int,false)*NaN)
println(convert(Int,false)*Inf)


0.0
0.0
NaN
NaN

Testing the Type

The perhaps easiest way to test the type is by using the isa(variable,Type) function. The type can be a union of other types (see below for an example).

Notice that an array has the type Array and more specifically, Array{Float64} if it is an array with Float64 numbers.


In [10]:
x = 1.2
z = [1.2,1.3]

println("$x is a Number: ",isa(x,Number))
println("$x is an Int: ",isa(x,Int))
println("$x is an Int or a Float64: ",isa(x,Union{Int,Float64}))

println("$z is a Float64: ",isa(z,Float64))
println("$z is an Array: ",isa(z,Array))


1.2 is a Number: true
1.2 is an Int: false
1.2 is an Int or a Float64: true
[1.2, 1.3] is a Float64: false
[1.2, 1.3] is an Array: true

Type Instability (extra)

Your code will often run faster if your variables do not change type in the computations. For instance, do not do something like this

x = 0                  #instead, do x = 0.0
x = x + 0.1

In [ ]: