What is this?
This is a calculator that works union of intervals Instead of just real numbers. It is an implementation of interval union arithmetic.
a gap [a, b] Represents the set of all numbers including a and b. An interval union:
[a, b] U [c, d] is a disjoint set of intervals.
interval Milan Regular interval arithmetic is an extension of regular interval arithmetic that is significantly better, mostly because it remains closed while supporting division by intervals containing zero:
➤ 2 / [-2, 1]
[-∞, -1] U [2, +∞]
The interesting thing about interval union arithmetic is the inclusion property, which means that if you choose any real number from each input union and compute the same expression on the reals, the result is guaranteed to be in the output union.
You can use this to represent uncertainty:
➤ 50 * (10 + [-1, 1])
[450, 550]
You can also calculate more complex interval expressions using the interval union operator U: :
➤ ( [5, 10] U [15, 16] ) / [10, 100]
[0.05, 1.6]
The operation may result in disjoint union of intervals:
➤ 1 / [-2, 1]
[-∞, -0.5] U [1, +∞]
➤ tan([pi/3, 2*pi/3])
[-∞, -1.732] U [1.732, +∞]
In full precision mode, you can use it as a regular calculator, and get interval results that are guaranteed to contain the correct values despite floating point precision issues:
➤ 0.1 + 0.2
[0.29999999999999993, 0.3000000000000001]
Syntax
| interval | [a, b] |
[0.5, 0.6] |
| Milan | [a, b] U [c, d] |
[0, 1] U [5, 6] |
| Add | A + B |
➤ [90, 100] + [-2, 2][88, 102] |
| subtraction | A - B |
➤ [14, 16] - [8, 12][2, 8] |
| multiply | A * B |
➤ [-5, 10] * [2, 4][-20, 40] |
| Division | A / B |
➤ [2, 4] / [-1, 2][-∞, -2] U [1, +∞] |
| exponent | A ^ B |
➤ [2, 3] ^ [-2, 3][0.1111, 27] |
| Work | function(...) |
➤ log10([1, 10000])[0, 4] |
| constant | name |
➤➤ pi[3.1415926535897927, 3.1415926535897936] |
Note: You can input the interval with the bracket syntax:
[1, 2]Or empty numbers without brackets: 3.14. The bare numbers are interpreted as a narrow interval, i.e. [3.14, 3.14] (With subtleties related to full precision mode). This enables empty numbers and intervals to be mixed naturally:
➤ 1.55 + [-0.002, 0.002]
[1.548, 1.552]
A wonderful result of the calculator grammar is that intervals can be nested and you can write things like this:
➤ [0, [0, 100]]
[0, 100]
This is because all numbers, including the numbers inside the interval brackets that define a range, are interpreted as an interval. When nesting two intervals as described above, the interval used as the interval boundary is equivalent to taking its upper limit. This design choice enables using arithmetic on interval limits:
➤ [0, cos(2*pi)]
[0, 1]
supported functions
| constant | inf,∞,pi, e |
➤ [-inf, 0] * [-inf, 0][0, +∞] |
| lower limit | lo(A) |
➤ lo([1, 2])[1, 1] |
| upper limit | hi(A) |
➤ hi([1, 2])[2, 2] |
| rudder | hull(A) |
➤ hull([1, 2] U [99, 100])[1, 100] |
| full value | abs(A) |
➤ abs([-10, 5])[0, 10] |
| square root | sqrt(A) |
➤ sqrt([9, 49])[3, 7] |
| square inverse | sqinv(A) |
➤ sqinv([4, 64])[-8, -2] U [2, 8] |
| Natural | log(A) |
➤ log([0, 1])[-∞, 0] |
| logarithm base 2 | log2(A) |
➤ log2([64, 1024])[6, 10] |
| logarithm base 10 | log10(A) |
➤ log10([0.0001, 1])[-4, 0] |
| exponential | exp(A) |
➤ exp([-∞, 0] U [1, 2])[0, 1] U [2.718, 7.389] |
| cosine | cos(A) |
➤ cos([pi/3, pi])[-1, 0.5] |
| sine | sin(A) |
➤ sin([pi/6, 5*pi/6])[0.5, 1] |
| tangent line | tan(A) |
➤ tan([pi/3, 2*pi/3])[-∞, -1.732] U [1.732, +∞] |
| archcos | acos(A) |
➤ acos([-1/2, 1/2])[1.047, 2.094] |
| arcsine | asin(A) |
➤ asin([0, 1])[0, 1.571] |
| arctan | atan(A) |
➤ atan([-10, 2])[-1.471, 1.107] |
| minimum | min(A, B) |
➤ min([1, 2], [0, 6])[0, 2] |
| maximum | max(A, B) |
➤ max([0, 10], [5, 6])[5, 10] |
full precision mode
Outward rounding is implemented on IEEE 754 double precision floats (JavaScript’s number type), so the result interval is guaranteed to contain real values that would be obtained by computing the same expression on the reals with infinite precision. For example, try the famous yoga
0.1 + 0.2 In the calculator. Interval arithmetic calculates an interval that is guaranteed to contain
0.3whether 0.3 Not representable as a double precision float.
When full precision mode is enabled:
- User-inputted numbers are interpreted as the smallest interval that contains the nearest IEEE 754 value of the input decimal representation but where none of the ranges are equal to
- The output numbers are displayed with all available decimal digits (using
Number.toString())
When full precision mode is disabled:
- User inputted numbers are interpreted as distorted intervals (width zero) where both limits are equal to the nearest IEEE 754 value of the input decimal representation.
- Output numbers are displayed with a maximum of 4 decimal digits (using
Number.toPrecision())
insects
Although I’ve been very careful, I’m sure there are still some bugs in the calculator. Please report any issues on GitHub.
open source
The Interval Calculator and Not-So-Float (the engine powering the calculator) are open-source. If you like my open-source work, please consider sponsoring me on GitHub. Thank you ❤️
future work
- Divide full precision mode into two controls: input interpretation and display precision.
- Add
ansVariable (result of previous entry) - Add intersection operator or function
- Make U’s preference more intuitive
- Help input empty union
<a href