Manual
The MicroFloatingPoints module
The central element of the MicroFloatingPoints package is the floating-point type Floatmu; it is parameterized by the sizes of the exponent field and the fractional part field.
MicroFloatingPoints.Floatmu — TypeFloatmu{szE,szf} <: AbstractFloatIEEE 754-compliant floating-point number with szE bits for the exponent and szf bits for the fractional part.
A Floatmu object must always have a precision smaller or equal to that of a single precision float. As a consequence, the following constraints hold:
\[\left\{\begin{array}{l} \text{szE}\in[2,8]\\ \text{szf}\in[2,23] \end{array}\right.\]
Examples
Creating a Floatmu type equivalent to Float32:
julia> MyFloat32 = Floatmu{8,23}
Floatmu{8, 23}
julia> a=MyFloat32(0.1)
0.1
julia> a == 0.1f0
trueCreating a Floatmu float
A Floatmu object may be created from a float from a standard floating-point type (Float16, Float32, Float64).
julia> Floatmu{8,23}(Float16(0.1))
0.099975586
julia> Floatmu{8,23}(0.1f0)
0.1
julia> Floatmu{8,23}(0.1)
0.1Note that, depending on the value and the size of the Floatmu type, some rounding may occur.
julia> Floatmu{2,2}(0.1f0)
0.0
julia> Floatmu{8,7}(0.1f0)
0.1Each Floatmu object retains the sign of the error due to rounding the value used to create it. That sign may be obtained with the method errorsign. If one is only interested in obtaining a boolean to know whether some rounding took place or not, one can use the isinexact method instead.
MicroFloatingPoints.errorsign — Methoderrorsign(x::Floatmu{szE,szf}) where {szE,szf}Return 1 if x was rounded by excess when created as a Floatmu{szE,szf}, -1 if it was rounded by default, and 0 if no rounding took place.
An NaN is never in error. An infinite is in error only if created from a finite value.
See
Examples
julia> errorsign(Floatmu{2, 2}(0.5))
0
julia> errorsign(Floatmu{2, 2}(1.7))
1
julia> errorsign(Floatmu{2, 2}(-2.8))
-1MicroFloatingPoints.isinexact — Methodisinexact(x::Floatmu{szE,szf}) where {szE,szf}Return true if the value x was rounded when created as a Floatmu{szE,szf} and false otherwise.
An NaN is never inexact. An infinite is inexact only if created from a finite value.
See:
Examples
julia> isinexact(Floatmu{2, 2}(0.25)+Floatmu{2, 2}(2.0))
true
julia> isinexact(Floatmu{2, 2}(0.25)+Floatmu{2, 2}(1.5))
falseBe wary of the fact that a Floatmu object is completely oblivious to rounding that may have occurred before the call of its constructor.
julia> isinexact(Floatmu{8,23}(Float16(0.1)))
falseIn the preceding example, no rounding is reported even though 0.1 is not representable in binary because the Floatmu is created from a Float16 approximation of it and a Floatmu{8,23} object has more precision than a Float16. The rounding that took place when creating the Float16 in the first place goes unreported.
It is also possible to create a Floatmu float from an integer of the type Int64:
julia> Floatmu{8,7}(10)
10.0Due to the limited precision of the Floatmu type, some rounding may still occur:
julia> Floatmu{8,7}(303)
304.0It is possible to know the largest positive integer such that all smaller integers are represented without rounding using the Base.maxintfloat method:
julia> maxintfloat(Floatmu{8,7})
256.0
julia> Floatmu{8,7}(257)
256.0Lastly, a Floatmu may be created from another Floatmu with the same or a different precision and range.
julia> Floatmu{5,10}(0.1)==Floatmu{8,7}(Floatmu{5,10}(0.1))
falseCharacteristics of a Floatmu
It is possible to obtain some characteristics of a Floatmu type by using standard Julia methods. Most of them are usually undocumented, being internal to the Base package. Since the intended audience for the MicroFloatingPoints package is probably more interested in these methods than the general public, we document them here.
The Base.precision() method returns the number of bits in the significand:
julia> Base.precision(Floatmu{8,23})
24The Base.exponent_max and Base.exponent_raw_max return, respectively, the maximum unbiased exponent and the maximum biased exponent.
julia> Base.exponent_max(Floatmu{8,23})
127
julia> Base.exponent_raw_max(Floatmu{8,23})
255Some other methods in the MicroFloatingPoints package are related to the exponent of a Floatmu:
MicroFloatingPoints.Emax — MethodEmax(::Type{Floatmu{szE,szf}}) where {szE, szf}Maximum unbiased exponent for a Floatmu{szE,szf} returned as an UInt32.
See: exponent_max, exponent_raw_max, Emin
Examples
julia> Emax(Floatmu{8, 23})
0x0000007fMicroFloatingPoints.Emin — MethodEmin(::Type{Floatmu{szE,szf}}) where {szE, szf}Minimum unbiased exponent for a Floatmu{szE,szf} returned as an Int32.
See: exponent_max, exponent_raw_max, Emax
Examples
julia> Emin(Floatmu{8, 23})
-126MicroFloatingPoints.bias — Methodbias(::Type{Floatmu{szE,szf}}) where {szE, szf}Bias of the exponent for a Floatmu{szE,szf}.
Examples
julia> bias(Floatmu{8, 23})
0x0000007fOther methods return remarkable values for the type:
MicroFloatingPoints.Infμ — MethodInfμ(::Type{Floatmu{szE,szf}}) where {szE,szf}Positive infinite value in the format Floatmu{szE,szf}.
Examples
julia> Infμ(Floatmu{8, 23}) == Inf32
trueMicroFloatingPoints.NaNμ — MethodNaNμ(::Type{Floatmu{szE,szf}}) where {szE, szf}NaN in the format Floatmu{szE,szf}.
The canonical NaN value has a sign bit set to zero and all bits of the fractional part set to zero except for the leftmost one.
Examples
julia> isnan(NaNμ(Floatmu{2, 2}))
true
julia> NaNμ(Floatmu{2, 2})
NaNμ{2, 2}Base.Math.ldexp — Methodldexp(x::Floatmu{szE,szf}, n::Integer) where {szE, szf}Return $x \times 2^n$.
This is a quick-and-dirty implementation.
Examples
julia> ldexp(Floatmu{5,3}(2.5),3)
20.0Base.eps — Methodeps(::Type{Floatmu{szE,szf}}) where {szE,szf}Return the epsilon of the type Floatmu{szE,szf}, which is the difference between 1.0 and the next float.
Examples
julia> eps(Floatmu{2, 2})
0.25
julia> eps(Floatmu{3, 5})
0.031
julia> eps(Floatmu{8, 23})==eps(Float32)
trueMicroFloatingPoints.λ — Methodλ(::Type{Floatmu{szE,szf}}) where {szE,szf}Return λ, the smallest positive normal number of the type Floatmu{szE,szf}.
Examples
julia> λ(Floatmu{2, 2})
1.0
julia> λ(Floatmu{8, 23})==floatmin(Float32)
trueMicroFloatingPoints.μ — Methodμ(::Type{Floatmu{szE,szf}}) where {szE,szf}Return μ, the smallest positive subnormal number of type Floatmu{szE,szf}.
Examples
julia> μ(Floatmu{2, 2})
0.25Base.sign — Methodsign(x::Floatmu{szE,szf}) where {szE, szf}Return x if x is zero, 1.0 if x is strictly positive and -1.0 if x is strictly negative. Return NaN if x is a Not a Number.
Examples
julia> sign(Floatmu{2, 3}(-1.6))
-1.0
julia> sign(Floatmu{2, 3}(1.6))
1.0
julia> sign(Floatmu{2, 3}(NaN))
NaNμ{2, 3}
julia> sign(Floatmu{2, 3}(-0.0))
-0.0Base.floatmax — Methodfloatmax(::Type{Floatmu{szE,szf}}) where {szE,szf}Return the largest positive normal number of the type Floatmu{szE,szf}.
Examples
julia> floatmax(Floatmu{2, 2})
3.5
julia> floatmax(Floatmu{8, 23})==floatmax(Float32)
trueBase.floatmin — Methodfloatmin(::Type{Floatmu{szE,szf}}) where {szE,szf}Return λ, the smallest positive normal number of the type Floatmu{szE,szf}.
Examples
julia> floatmin(Floatmu{2, 2})
1.0
julia> floatmin(Floatmu{8, 23})==floatmin(Float32)
trueBase.typemin — Methodtypemin(::Type{Floatmu{szE,szf}}) where {szE,szf}Return the negative infinite of the type Floatmu{szE,szf}.
Examples
julia> typemin(Floatmu{3, 5})
-Infμ{3, 5}Base.typemax — Methodtypemax(::Type{Floatmu{szE,szf}}) where {szE,szf}Return the positive infinite of the type Floatmu{szE,szf}.
Examples
julia> typemax(Floatmu{3, 5})
Infμ{3, 5}Base.maxintfloat — Methodmaxintfloat(::Type{Floatmu{szE,szf}}) where {szE,szf}Return the smallest positive integer $n$ such that $n+1$ is not representable in the type Floatmu{szE,szf}. The number $n$ is returned as a Floatmu{szE,szf}.
The function returns an infinite value if all integers are representable in the domain of normal values.
Examples
julia> maxintfloat(Floatmu{3,2})
8.0
julia> maxintfloat(Floatmu{2,2})
Infμ{2, 2}
julia> maxintfloat(Floatmu{8,23})==maxintfloat(Float32)
trueLastly, some methods test properties on the different parts of a Floatmu:
MicroFloatingPoints.fractional_even — Methodfractional_even(x::Floatmu{szE,szf}) where {szE,szf}Return true if the fractional part of x has a zero as the rightmost bit.
BEWARE: the function does not check whether x is an NaN or an infinite value.
Tests
Base.signbit — Methodsignbit(x::Floatmu{szE,szf}) where {szE, szf}Return true if x is signed and false otherwise. The result for a NaN may vary, depending on the value of its sign bit.
Examples
julia> signbit(Floatmu{2, 3}(1.5))
false
julia> signbit(Floatmu{2, 3}(-1.5))
trueThe function differentiates between $-0.0$ and $+0.0$ even though both values test equal.
julia> signbit(Floatmu{2, 3}(-0.0))
true
julia> signbit(Floatmu{2, 3}(0.0))
falseBase.isnan — Methodisnan(x::Floatmu{szE,szf}) where {szE,szf}Return true if x is a Not an Number and false otherwise.
Examples
julia> isnan(Floatmu{2, 3}(1.5))
false
julia> isnan(Floatmu{2, 3}(NaN))
trueBase.isinf — Methodisinf(x::Floatmu{szE,szf}) where {szE,szf}Return true if x is an infinity and false otherwise.
Examples
julia> isinf(Floatmu{2, 2}(1.5))
false
julia> isinf(Floatmu{2, 2}(-Inf))
true
julia> isinf(Floatmu{2, 2}(9.8))
trueBase.isfinite — Methodisfinite(x::Floatmu{szE,szf}) where {szE,szf}Return true if x is finite and false otherwise. An NaN is not finite.
Examples
julia> isfinite(Floatmu{2, 2}(1.5))
true
julia> isfinite(Floatmu{2, 2}(3.8))
false
julia> isfinite(Floatmu{2, 2}(NaN))
falseBase.issubnormal — Methodissubnormal(x::Floatmu{szE,szf}) where {szE,szf}Return true if x is a subnormal number and false otherwise. According to the definition, ±0.0 is not a subnormal number.
Examples
julia> issubnormal(Floatmu{2, 2}(1.0))
false
julia> issubnormal(Floatmu{2, 2}(0.25))
true
julia> issubnormal(Floatmu{2, 2}(0.0))
falseConversions
A Floatmu may be converted from and to any of the standard floating-point type (Float16, Float32, Float64).
Base.convert — Functionconvert(::Type{Float64}, x::Floatmu{szE,szf}) where {szE, szf}
convert(::Type{Float32}, x::Floatmu{szE,szf}) where {szE, szf}
convert(::Type{Float16}, x::Floatmu{szE,szf}) where {szE, szf}
convert(::Type{Floatmu{szE,szf} where {szE,szf}}, x::Float64)
convert(::Type{Floatmu{szE,szf} where {szE,szf}}, x::Float32)
convert(::Type{Floatmu{szE,szf} where {szE,szf}}, x::Float16)Convert a Floatmu to a double, single or half precision float, or vice-versa. For the double precision, the conversion never introduces errors since Float64 objects have at least twice the precision of the fractional part of a Floatmu object.
Examples
julia> convert(Float64,Floatmu{8, 23}(0.1))
0.10000000149011612
julia> convert(Float32,Floatmu{8, 23}(0.1)) == 0.1f0
true
julia> convert(Float32,Floatmu{5, 10}(0.1)) == Float16(0.1)
true
julia> convert(Floatmu{2, 4},0.1)
0.12
julia> convert(Floatmu{2, 4},0.1f0)
0.12
julia> convert(Floatmu{2, 4},Float16(0.1))
0.12
julia> Floatmu{5, 10}(0.1)==Float16(0.1)
trueA Floatmu may also be created from a string:
Base.parse — Methodparse(::Type{Floatmu{szE,szf}}, str::AbstractString) where {szE, szf}Parse the string str representing a floating-point number and convert it to a Floatmu{szE,szf} object.
Examples
julia> parse(Floatmu{5, 7},"0.1")
0.1
julia> parse(Floatmu{5, 7},"1.0e10")
Infμ{5, 7}The string is first converted to a Float64 and then rounded to the precision of the Floatmu object. If the string cannot be converted to a Float64, the ArgumentError exception is thrown.
Examples
julia> parse(Floatmu{5, 7},"0.1a")
ERROR: ArgumentError: cannot parse "0.1a" as a Floatmu{5, 7}Base.tryparse — Methodtryparse(::Type{Floatmu{szE,szf}}, str::AbstractString) where {szE, szf}Parse the string str representing a floating-point number and convert it to a Floatmu{szE,szf} object.
Examples
julia> tryparse(Floatmu{5, 7},"0.1")
0.1
julia> tryparse(Floatmu{5, 7},"1.0e10")
Infμ{5, 7}The string is first converted to a Float64 and then rounded to the precision of the Floatmu object. Contrary to parse, if the string cannot be converted to a Float64, the value nothing is returned.
Examples
julia> tryparse(Floatmu{5, 7},"0.1a") == nothing
trueDisplay
Contrary to a Float16 or a Float32, which are displayed by default with an indication of their type, a Floatmu is displayed as a number alone with no indication of its type (much like a Float64).
julia> Floatmu{2,2}(0.25)
0.25It is also possible to display the internal representation of a Floatmu{szE,szf} as an $1+\text{szE}+\text{szf}$ bit string:
Base.bitstring — Methodbitstring(x::Floatmu{szE,szf}) where {szE,szf}Return the string of bits representing internally the value x.
Examples
julia> bitstring(Floatmu{2, 2}(1.5))
"00110"
julia> bitstring(Floatmu{2, 2}(0.5))
"00010"
julia> bitstring(Floatmu{8, 23}(0.1))==bitstring(0.1f0)
true
julia> bitstring(Floatmu{8, 23}(Inf)) == bitstring(Inf32)
trueIterating through floats
As for the standard floating-point types, it is possible to go from one Floatmu to the next using nextfloat and prevfloat.
Base.prevfloat — Methodprevfloat(x::Floatmu{szE,szf}, n::UInt32 = 1) where {szE,szf}Return the Floatmu{szE,szf} float that is n floats before x in the natural order of floats. Return NaNμ{szE,szf} if x is Not a Number. Return -Infμ{szE,szf} if there are less than n finite floats before x on the real line.
Examples
julia> prevfloat(Floatmu{2, 2}(1.0),2)
0.5
julia> prevfloat(Floatmu{2, 2}(-0.0))
-0.25
julia> prevfloat(Floatmu{2, 2}(Inf))
3.5
julia> prevfloat(Floatmu{2, 2}(0.25))
0.0Base.nextfloat — Methodnextfloat(x::Floatmu{szE,szf}, n::UInt32 = 1) where {szE,szf}Return the Floatmu{szE,szf} float that is n floats after x in the natural order of floats. Return NaNμ{szE,szf} if x is Not a Number. Return Infμ{szE,szf} if there are less than n finite floats after x on the real line.
Examples
julia> nextfloat(Floatmu{2, 2}(3.5))
Infμ{2, 2}
julia> nextfloat(Floatmu{2, 2}(0.0),3)
0.75
julia> nextfloat(Floatmu{2, 2}(-Inf))
-3.5
julia> nextfloat(Floatmu{2, 2}(-0.25))
-0.0A FloatmuIterator allows to iterate on a range of Floatmu in a more systematic way:
MicroFloatingPoints.FloatmuIterator — TypeFloatmuIterator(start::Floatmu{szE,szf},stop::Floatmu{szE,szf},
step::Floatmu{szE,szf}) where {szE,szf}
FloatmuIterator(start::Floatmu{szE,szf},stop::Floatmu{szE,szf},
step::Float64) where {szE,szf}
FloatmuIterator(start::Floatmu{szE,szf},stop::Floatmu{szE,szf},
step::Int = 1) where {szE,szf}
FloatmuIterator(::Type{Floatmu{szE,szf}},start::Float64,stop::Float64,
step::Int = 1) where {szE,szf}
FloatmuIterator(::Type{Floatmu{szE,szf}},start::Float64,stop::Float64,
step::Float64) where {szE,szf}Iterator to generate all Floatmu{szE,szf} in the domain [start,stop]. The iterator can be initialized with two Floatmu{szE,szf} or with two Float64.
One may iterate from one float to the next (the default) or choose some step. The step may be a number of floats or an amount to add.
An ArgumentError is raised if the bounds are NaNs, if the step chosen is zero (or rounds to zero when converted to a Floatmu{szE,szf}), or if the step is a value smaller than the largest distance between two consecutive floats in [last, stop] (use eligible_step to know the smallest value allowed).
When the step is an amount to add, the bounds cannot be infinities.
When the step is a number of floats, infinities are allowed for the bounds and are always part of the resulting range:
julia> collect(FloatmuIterator(Floatmu{2,2},-Inf,Inf,5))
6-element Vector{Floatmu{2, 2}}:
-Infμ{2, 2}
-1.8
-0.5
0.75
2.0
Infμ{2, 2}Examples
julia> L=[x for x = FloatmuIterator(Floatmu{2, 2}(0.0), Floatmu{2, 2}(1.0))]
5-element Vector{Floatmu{2, 2}}:
0.0
0.25
0.5
0.75
1.0
julia> L2=[x for x = FloatmuIterator(Floatmu{2, 2}, 0.0, 1.0, 2)]
3-element Vector{Floatmu{2, 2}}:
0.0
0.5
1.0Keep in mind that the bounds of the iterator may need rounding when converted to a Floatmu, so that the number of iterations may not be the one expected. Additionnally, the step chosen may induce more rounding at each iteration.
Example
julia> [x for x in FloatmuIterator(Floatmu{2,2},-1.2,-0.2,0.3)]
4-element Vector{Floatmu{2,2}}:
-1.25
-1.0
-0.75
-0.5
julia> FloatmuIterator(Floatmu{2,2},-1.2,-0.2,0.3)
FloatmuIterator{2,2}(-1.25, -0.25, 0.25)It is possible to know in advance the number of floats in the resulting range with the length function.
As stated in the documentation for FloatmuIterator above, one cannot use a floating-point step smaller than the largest gap in the domain we iterate through. The function eligible_step gives the smallest value allowed when given two bounds.
MicroFloatingPoints.eligible_step — Functioneligible_step(start::Floatmu{szE,szf}, stop::Floatmu{szE,szf}) where {szE,szf}
eligible_step(::Type{Floatmu{szE,szf}}, start::Float64, stop::Float64) where {szE,szf}Return the smallest Floatmu{szE,szf} eligible step allowed to iterate through the domain [start,stop].
Examples
julia> eligible_step(Floatmu{2,2}(-0.5),Floatmu{2,2}(2.5))
0.5Rounding
We have seen in section Creating a Floatmu float that each Floatmu retains the information whether the value it was created from required rounding or not.
In addition to that mechanism, the MicroFloatingPoints module keeps a global state that is set to true every time a Floatmu is created and rounding takes place. It has a sticky behavior (once true, it stays true until reset explictly to false). It can be checked with the inexact() method and reset with the reset_inexact() method.
MicroFloatingPoints.inexact — Methodinexact()Return the value of the inexact flag. Each task possesses its own copy of the variable.
See also reset_inexact.
MicroFloatingPoints.reset_inexact — Methodreset_inexact()Reset the inexact flag to false. Each task possesses its own copy of the variable.
See also inexact.
With these methods, one can check whether some computation needed rounding at some point:
julia> reset_inexact()
julia> inexact()
false
julia> Floatmu{2,2}(2.0)+Floatmu{2,2}(0.25)
2.0
julia> inexact()
true
julia> reset_inexact()
julia> Floatmu{2,2}(2.0)+Floatmu{2,2}(0.25)+Floatmu{2,2}(0.25)
2.0
julia> inexact()
trueNote that, in the first example, the result of the computation needed rounding, while in the second example, the output is representable but one of the intermediary computation needed rounding.
The MicroFloatingPoints.MFPUtils module
The MicroFloatingPoints.MFPUtils module offers some utiliy functions to be used either by other modules of the MicroFloatingPoints package or directly by the end user.
MicroFloatingPoints.MFPUtils.vertical_popcount — Methodvertical_popcount(T::Vector{Floatmu{szE,szf}}) where {szE,szf}Return a vector R of size 1+szE+szf where R[i] is the number of times the i-th bit of the values in T was equal to 1.
For this function, the rightmost bit of the binary representation of a Floatmu has index 1 and not 0 as usual.
Examples
julia> join(string.(reverse(vertical_popcount(Floatmu{2,2}[1.5])))) == bitstring(Floatmu{2,2}(1.5))
trueNote that, in the preceding example, we have to revert the array obtained from vertical_popcount because the number of times bit i is 1 is saved at position i. As a consequence, the value for the rightmost bit of a Floatmu appears at the leftmost position of the counting array.
julia> println(vertical_popcount(Floatmu{2,2}[0.25,1.5,3.0]))
[1, 2, 1, 1, 0]The MicroFloatingPoints.MFPRandom module
The MicroFloatingPoints.MFPRandom module overloads rand to offer Floatmu floating-point numbers drawn at random in $[0,1)$. The method uses Random.rand under the hood. It is then affected in the same way by Random.seed!.
julia> Random.seed!(42);
julia> rand(Floatmu{2,2})
0.5
julia> rand(Floatmu{2,2})
0.25It is possible to draw Floatmu values at random in the same way as with other floating-point types:
julia> rand(Floatmu{2,2},5)
5-element Vector{Floatmu{2, 2}}:
0.25
0.5
0.5
0.0
0.5Using the Distributions package, one can also draw Floatmu numbers with other distributions:
julia> rand(Uniform(Floatmu{2,2}(-1.0),Floatmu{2,2}(1.0)))
0.25One must be wary of very small Floatmu types when using other distributions than $U[0,1)$ as the computation necessary to compute another distribution may easily involve larger numbers than can be represented with the type. Consider, for example, the type Floatmu{2,2} whose largest positive finite value is 3.0. If we decide to draw numbers in the domain $[-2,2)$, we will call:
rand(Uniform(Floatmu{2,2}(-2.0),Floatmu{2,2}(2.0)))To translate the distribution from $[0,1)$ to $[-2,2)$, the Uniform method will draw a value $x$ in $[0,1)$ and apply the formula $a+(b-a)x$, with $a=-2$ and $b=2$. Unfortunately, $b-a$ will then be $\text{Floatmu\{2,2\}}(2.0)-\text{Floatmu}\{2,2\}(-2.0)$, which is rounded to Infμ{2,2}. Consequently, we will always draw the same infinite value:
julia> rand(Uniform(Floatmu{2,2}(-2.0),Floatmu{2,2}(2.0)))
Infμ{2, 2}
julia> rand(Uniform(Floatmu{2,2}(-2.0),Floatmu{2,2}(2.0)))
Infμ{2, 2}
The MicroFloatingPoints.MFPPlot module
The MicroFloatingPoints.MFPPlot module offers some methods to easily represent floating-point numbers. It currently supports both PyPlot and PythonPlot backends, one of which must be loaded. To use PythonPlot, replace references to PyPlot with PythonPlot below and create the following alias for plt.
const plt = PythonCall.pyplotMicroFloatingPoints.MFPPlot.real_line — Functionreal_line(start::Floatmu{szE,szf}, stop::Floatmu{szE,szf};
ticks = true,
fpcolorsub = "purple", fpcolornorm = "blue") where {szE,szf}
real_line(::Type{Floatmu{szE,szf}};
ticks = true,
fpcolorsub = "purple", fpcolornorm = "blue",
fpcolorinf="orange") where {szE,szf}
real_line(T::Vector{Floatmu{szE,szf}};
ticks = true, fpcolorsub = "purple", fpcolornorm = "blue",
fpcolorinf="orange") where {szE,szf}Draw floats on the real line.
The first version draws the real line between start and stop and displays all floating-point numbers with sze bits exponent and szf bits fractional part. The second version draws all finite floating-point for the format Floatmu{szE,szf} and adds the infinities where the next/previous float would be with the format Floatmu{szE+1,szf}. The third version draws all floats in the vector T.
In the first version, both parameters start and stop must be finite. An ArgumentError exception is raised otherwise. The same goes for all values in T for the third version.
All versions return the figure used for the plot.
The figure may be customized through the named parameters:
ticks: iftrue, draws a vertical line for each float and adds the value below. Iffalse, represent each float by a dot on the real line, without its value;fpcolorsub: color of the line or dot used to represent subnormals;fpcolornorm: color of the line or dot used to represent normal values;fpcolorinf[for the second version only]: color of the line or dot used to represent infinite values.
Examples of calls
real_line(-floatmax(Floatmu{2,2}),floatmax(Floatmu{2,2}));
real_line(Floatmu{2,2});
real_line(Floatmu{2,2}[-3.5,0.25,1.5,2.0])Examples
julia> real_line(Floatmu{2,3}(-2.5),Floatmu{2,3}(1.0));
julia> real_line(Floatmu{2,3});
MicroFloatingPoints.MFPPlot.bits_histogram — Functionbits_histogram(T::Vector{Floatmu{szE,szf}};
signcolor = "magenta",
expcolor = "darkolivegreen",
fraccolor = "blue") where {szE,szf}Draw an histogram of the probability of each bit of the representation of a float to be 1 in the sample T.
julia> T=collect(FloatmuIterator(Floatmu{3,5},0.0,1.0,2.0^-6));julia> bits_histogram(T)