Easy Tutorial
❮ Julia Flow Control Julia Basic Operators ❯

Julia Data Types

There is also a term called "literal", which is used to express a fixed value in source code notation. Integers, floating-point numbers, and strings are all examples of literals.

For instance:

Julia provides a rich set of primitive numeric types and a comprehensive set of arithmetic operations defined on them. It also offers bitwise operators and some standard mathematical functions.


Integer Types

The table below lists the integer types supported by Julia:

Type Signed? Bits Minimum Value Maximum Value
Int8 8 -2^7 2^7 – 1
UInt8 8 0 2^8 – 1
Int16 16 -2^15 2^15 – 1
UInt16 16 0 2^16 – 1
Int32 32 -2^31 2^31 – 1
UInt32 32 0 2^32 – 1
Int64 64 -2^63 2^63 – 1
UInt64 64 0 2^64 – 1
Int128 128 -2^127 2^127 – 1
UInt128 128 0 2^128 – 1
Bool N/A 8 false (0) true (1)

Integer literal forms:

Example

julia> 1
1

julia> 1234
1234

The default type of an integer literal depends on whether the target system is a 32-bit or 64-bit architecture (most systems are now 64-bit):

Example

# 32-bit system:
julia> typeof(1)
Int32

# 64-bit system:
julia> typeof(1)
Int64

Julia's built-in variable Sys.WORD_SIZE indicates whether the target system is a 32-bit or 64-bit architecture:

Example

# 32-bit system:
julia> Sys.WORD_SIZE
32

# 64-bit system:
julia> Sys.WORD_SIZE
64

Julia also defines the types Int and UInt, which are aliases for the system's native signed and unsigned integer types, respectively.

Example

# 32-bit system:
julia> Int
Int32
julia> UInt
UInt32

# 64-bit system:
julia> Int
Int64
julia> UInt
UInt64

Overflow Behavior

In Julia, exceeding the maximum value that a type can represent results in wraparound behavior:

Example

julia> x = typemax(Int64)
9223372036854775807

julia> x + 1
-9223372036854775808

julia> x + 1 == typemin(Int64)
true

Thus, Julia's integer arithmetic is essentially a form of modular arithmetic, reflecting the characteristics of modern computer implementations of low-level arithmetic. In programs where overflow may occur, it is necessary to explicitly check for loops at the boundary of the maximum values. Otherwise, it is recommended to use the BigInt type from arbitrary precision arithmetic as an alternative.

Here is an example of overflow behavior and how to resolve it:

Example

julia> 10^19
-8446744073709551616

julia> big(10)^19
10000000000000000000

Division Errors

The rem remainder function and mod modulo function throw a DivideError when dividing by zero, as shown in the following example:

Example

julia> mod(1, 0)
ERROR: DivideError: integer division error
Stacktrace:
 [1] div at .\int.jl:260 [inlined]
 [2] div at .\div.jl:217 [inlined]
 [3] div at .\div.jl:262 [inlined]
 [4] fld at .\div.jl:228 [inlined]
 [5] mod(::Int64, ::Int64) at .\int.jl:252
 [6] top-level scope at REPL[52]:1

julia> rem(1, 0)
ERROR: DivideError: integer division error
Stacktrace:
 [1] rem(::Int64, ::Int64) at .\int.jl:261
 [2] top-level scope at REPL[54]:1

Floating-Point Types

The table below lists the floating-point types supported by Julia:

Type Precision Bits
Float16 Half 16
Float32 Single 32
Float64 Double 64

Additionally, full support for complex and rational numbers is built on top of these primitive data types.

Floating-point literals are formatted as follows, with the option to use E when necessary.

Example

julia> 1.0
1.0

julia> 1.
1.0

julia> 0.5
0.5

julia> .5
0.5

julia> -1.23
-1.23

julia> 1e10
1.0e10

julia> 2.5e-4
0.00025

Note: The format with E represents exponentiation. For example, 1.03 times 10 to the power of 8 can be abbreviated as "1.03E+08", where "E" stands for exponent.

The results above are all of type Float64. Using f instead of e yields literals of type Float32:

Example

julia> x = 0.5f0
0.5f0

julia> typeof(x)
Float32

julia> 2.5f-4
0.00025f0

Values can be easily converted to Float32:

julia> x = Float32(-1.5)
-1.5f0

julia> typeof(x)
Float32

Hexadecimal floating-point literals also exist but are only applicable to Float64 values. They are generally represented with a p prefix and an exponent base of 2:

Example

julia> 0x1p0
1.0

julia> 0x1.8p3
12.0

julia> x = 0x.4p-1
0.125

julia> typeof(x)
Float64

Julia also supports half-precision floating-point numbers (Float16), but they are implemented in software using Float32.

julia> sizeof(Float16(4.))
2

julia> 2*Float16(4.)
Float16(8.0)

The underscore _ can be used as a numeric separator:

Example

julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010
(10000, 5.0e-9, 0xdeadbeef, 0xb2)

Zeros in Floating-Point Numbers

There are two types of zeros in floating-point numbers, positive zero and negative zero. They are equal to each other but have different binary representations, which can be viewed using the bitstring function:

Example

julia> 0.0 == -0.0
true

julia> bitstring(0.0)
### Special Floating-Point Values

There are three specific standard floating-point values that do not correspond to any point on the real number line:

| Float16 | Float32 | Float64 | Name | Description |
| --- | --- | --- | --- | --- |
| Inf16 | Inf32 | Inf | Positive Infinity | A number greater than all finite floating-point numbers |
| -Inf16 | -Inf32 | -Inf | Negative Infinity | A number less than all finite floating-point numbers |
| NaN16 | NaN32 | NaN | Not a Number | A value that is not equal (==) to any floating-point value, including itself |

Here are some examples of floating-point arithmetic:

## Example

```julia
julia> 1/Inf
0.0

julia> 1/0
Inf

julia> -5/0
-Inf

julia> 0.000001/0
Inf

julia> 0/0
NaN

julia> 500 + Inf
Inf

julia> 500 - Inf
-Inf

julia> Inf + Inf
Inf

julia> Inf - Inf
NaN

julia> Inf * Inf
Inf

julia> Inf / Inf
NaN

julia> 0 * Inf
NaN

julia> NaN == NaN
false

julia> NaN != NaN
true

julia> NaN < NaN
false

julia> NaN > NaN
false

We can also use the typemin and typemax functions:

Example

julia> (typemin(Float16), typemax(Float16))
(-Inf16, Inf16)

julia> (typemin(Float32), typemax(Float32))
(-Inf32, Inf32)

julia> (typemin(Float64), typemax(Float64))
(-Inf, Inf)

Machine Precision

Most real numbers cannot be represented exactly by floating-point numbers, so it is necessary to know the distance between two adjacent representable floating-point numbers, which is commonly called machine epsilon.

Julia provides the eps function, which gives the difference between 1.0 and the next floating-point number that Julia can represent:

Example

julia> eps(Float32)
1.1920929f-7

julia> eps(Float64)
2.220446049250313e-16

julia> eps() # same as eps(Float64)
2.220446049250313e-16

These values are 2.0^-23 for Float32 and 2.0^-52 for Float64. The eps function can also take a floating-point value as an argument and return the absolute difference between that value and the next representable floating-point number. That is, eps(x) produces a value of the same type as x, and x + eps(x) is the next representable floating-point number larger than x:

Example

julia> eps(1.0)
2.220446049250313e-16

julia> eps(1000.0)
1.1368683772161603e-13

julia> eps(1e-27)
1.793662034335766e-43

julia> eps(0.0)
5.0e-324

The distance between two adjacent representable floating-point numbers is not constant; the smaller the value, the smaller the gap, and the larger the value, the larger the gap. In other words, representable floating-point numbers are densest around zero on the real number line and become increasingly sparse as they move away from zero, growing exponentially. By definition, eps(1.0) is equal to eps(Float64) because 1.0 is a 64-bit floating-point value.

Julia also provides the nextfloat and prevfloat functions, which return the next larger or smaller representable floating-point number based on the argument:

Example

julia> x = 1.25f0
1.25f0

julia> nextfloat(x)
1.2500001f0

julia> prevfloat(x)
1.2499999f0

julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"

julia> bitstring(x)
"00111111101000000000000000000000"

julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"
This example demonstrates a general principle, which is that adjacent representable floating-point numbers also have adjacent binary integer representations.

---

## Rounding Modes

If a number does not have an exact floating-point representation, it must be rounded to an appropriate representable value.

The default mode used by Julia is always `RoundNearest`, which means rounding to the nearest representable value, with preference for the value that uses the least significant digits.

## Example

julia> BigFloat("1.510564889",2,RoundNearest) 1.5

julia> BigFloat("1.550564889",2,RoundNearest) 1.5

julia> BigFloat("1.560564889",2,RoundNearest) 1.5


---

## Literals for 0 and 1

Julia provides literal functions for 0 and 1 that can return a specific type or the type of a given variable.

| Function | Description |
| --- | --- |
| zero(x) | Zero literal of the type of x or variable x |
| one(x) | One literal of the type of x or variable x |

These functions can be used in numerical comparisons to avoid the overhead of unnecessary type conversions.

## Example

julia> zero(Float32) 0.0f0

julia> zero(1.0) 0.0

julia> one(Int32) 1

julia> one(BigFloat) 1.0


---

## Type Conversion

Type conversion is the process of converting a variable from one type to another. For example, if you want to store a float value into a simple integer type, you need to cast the float type to int type. You can use the type cast operator to explicitly convert a value from one type to another, as shown below:

**First Method:**

T(x) or convert(T,x)


Both will convert x to type T.

- If T is a floating-point type, the result of the conversion will be the nearest representable value, which could be positive or negative infinity.

- If T is an integer type, an InexactError will be thrown if x cannot be represented by type T.

**Second Method:**

`x % T` can also convert integer x to integer type T, with the result being consistent with x modulo 2^n, where n is the number of bits in T.

**Third Method:**

Rounding functions accept an optional parameter of type T. For example, `round(Int,x)` is a shorthand for `Int(round(x))`.

## Example

julia> Int8(127) 127

julia> Int8(128) ERROR: InexactError: trunc(Int8, 128) Stacktrace: [...]

julia> Int8(127.0) 127

julia> Int8(3.14) ERROR: InexactError: Int8(3.14) Stacktrace: [...]

julia> Int8(128.0) ERROR: InexactError: Int8(128.0) Stacktrace: [...]

julia> 127 % Int8 127

julia> 128 % Int8 -128

julia> round(Int8,127.4) 127

julia> round(Int8,127.6) ERROR: InexactError: trunc(Int8, 128.0) Stacktrace: [...] ```

❮ Julia Flow Control Julia Basic Operators ❯