# FlexFloat.jl

#### These are values that stretch preserve accuracy.

The underlying representation is an interval with bounds that may be closed (exact) or open (inexact). An exact bound takes the floating point value given at that boundry to be a precisely accurate quantity. Two examples of exact quantities are counts and monetary balances. An inexact bound takes the floating point value given at the lower [higher] boundry to be largest [smallest] possible quantity to be included in the bounding value's span. An inexact bound bound extendes away from the center of the interval, almost reaching the next lower [higher] floating point value. Inexact bounds cover a real span that is not fully representable with machine floats -- and from that fact tend to follow results with relatively tight bounds.

The package internals handle all of that without additional guidance. There are four kinds of intervals:

```
(a) both bounds are exact (closed): clcl(1,2)
(b) both bounds are inexact (open): oppp(1,2)
(c) only the lower bound is exact : clop(1,2)
(d) only the upper bound is exact : opcl(1,2)
```

An exact value of 1 is entered as Exact(1). Exact is a synonym for clcl.

An interval with exact bounds of zero and one is entered as Exact(0,1).

An inexact value of 3 is entered as Inexact(3). Inexact is a synonym for opop.

this indicates any value within the Real range that extends from prevfloat(3) to nextfloat(3) without including either.

The inexact interval Inexact(1,2) indicates any value within the Real range from prevfloat(1) to nextfloat(2), exclusively.

#### Any values may exist in one of two states

###### states 'exact', 'inexact' are exported; 'situated', 'enhanced' are the internal names.

*This capability exists transparently -- apps that do not need it do not see it.*

Each Flex may be [re]assigned either of two states and the statefulness persists unless reassigned. There is no limit on state changes, nor any requirement that states change. The state is independant of the kind of interval (ClCl, OpOp, ClOp, OpCl); one may create some logical dependance in code. To simplify use,

```
clcl(), opop(), clop(), opcl() create values in the 'inexact' stat
ClCl(), OpOp(), ClOp(), OpCl() create values in the 'exact' state
(lowercase is used with situated values, titlecase with enhanced values)
Assignment, determination and utilization of statefulness is entirely given to your application.
op(a,b) where isexact(a)&isinexact(b) and a,b are not of the same sculpture
is not predefinded, nor are associated conversions .. **encode your intent**.
```

The file 'src/type/cvtqualia.jl' has the comparison and conversion defaults for statefulness.

###Quick Guide

```
#=
a closed boundry (an exact bound) is shown with single angle brackets
an open boundry (an inexact bound) is shown with double angle brackets
when the lower bound and the upper bound are equal one number is shown
when the lower bound and the upper bound are equal, one may use it alone
values in the 'exact' state are tied with '⌁', '~' ties 'inexact' values
=#
julia> opop(1.2345,1.2346), ClCl(1), clcl(1,1), OpOp(1.2,1.2)
(⟪1.2345⌁1.2346⟫,⟨1.0⌁⟩,⟨1.0~⟩,⟪1.2~⟫)
# different sorts of values may be intermixed for arithmetic
julia> a=clcl(2.0); b=opcl(1.5, 2.0); a-b, a*b, a/b
(⟪0.0⌁0.5⟩,⟪3.0⌁4.0⟩,⟪1.0⌁1.3333333333333335⟩)
# Flex64 is a typealias, it works like clcl()
julia> Flex64(1.0)
⟨1.0⌁2.0⟩
julia> Flex64(1.0,2.0)
⟨1.0⌁2.0⟩
```

###And More

```
# elementary functions of FlexFloat values
julia> using FlexFloat
julia> exp(OpOp(1.0))
⟨2.7182818284590446~2.7182818284590455⟩ # diameter: 8.88e-16
# optionally using CRlibm for more accuracy
julia> using CRlibm # must preceed using FlexFloat
julia> using FlexFloat
julia> exp(OpOp(1.0))
⟨2.718281828459045~2.7182818284590455⟩ # diameter: 4.44e-16
# polynomial evaluation at FlexFloat values
julia> using Polynomials
julia> using FlexFloat
julia> p = Poly([4.0,8,1,-5,-1,1]);
julia> polyval(p,OpOp(2.5,2.5+eps(2.5)))
⟪10.718749999999991~10.718750000000039⟫
# cdf, pdf, quantile at FlexFloat values
# for continuous univariate distributions
julia> using Distributions # must preceed using FlexFloat
julia> using FlexFloat
julia> ND=normal();
julia> pdf(ND, ClCl(0.999,0.9995))
⟨0.24209170987131956~0.24221269516298546⟩
julia> pdf(ND, OpOp(0.999,0.9995))
⟨0.24209170987131953~0.24221269516298546⟩
```

###### supports

```
(==), (!=), (<), (<=), (>=), (>),
(+), (-), (*), (/),
sqrt, exp, log,
sin, cos, tan, csc, sec, cot,
asin, acos, atan, acsc, asec, acot,
sinh, cosh, tanh, csch, sech, coth,
asinh, acosh, atanh, acsch, asech, acoth,
erf, erfinv
when the Distributions package is pre-loaded:
cdf, pdf, quantile for univariate continuous distributions
```

###### References

(please see doc/References.md for all referenced material and links)

John L. Gustafson, *The End of Error: Unum Computing*

Ulrich Kulisch, *Up-to-date Interval Arithmetic*