Tutorial
Для использования библиотеки JInterval её прежде всего надо скачать.
Исходники JInterval
Исходники JInterval хранятся в репозитории Subversion. Установите на своем компьютер пакет с клиентом Subversion
После этого такая командная строка скачает всю информацию, имеющуюся в репозитории.
svn co https://svn.kenai.com/svn/jinterval~svn
Для экономии места можно скачать только проект JInterval_all_include
svn co https://svn.kenai.com/svn/jinterval~svn/home/egor/JInterval_all_include
Теперь (если на компьютере установлен Netbeans) можно открыть проект в каталоге JInterval_all_include и собрать его.
Jar архив
Если нет желания собирать JInterval самому, можно скачать собранный jar-архив.
В этом случае список имеющихся классов и методов можно просмотреть в JInterval apidocs.
Как использовать JInterval
- Создайте в Netbeans Java-проект.
- Слева в закладке проекты кликните правой кнопкой мыши на узел <Имя проекта>/Библиотеки.
- Если скачано дерево исходников поекта, то выберите "Добовить проект..." и выберите директорию JInterval_all_include.
- Если скачан только jar-архив, то выберите "Добавить архив jar или папку..." и выберите скачанный jar-архив.
- Введите простую программу типа
package jintervaltutorial;
import com.kenai.jinterval.rational_bounds.RealInterval;
public class simple {
public static void main(String[] args) {
System.out.println("test "+RealInterval.currentRoundingMode() + " "+RealInterval.currentRelativeAccuracy());
RealInterval x = RealInterval.valueOf(1.0, 2.0);
RealInterval y = RealInterval.valueOf(3.0, 4.0);
RealInterval s = x.add(y);
RealInterval q = x.divide(y);
System.out.println("x="+x);
System.out.println("y="+y);
System.out.println("x+y="+s);
System.out.println("x/y="+q);
}
}
При запуске она выдаст
test OUTWARDS +0x3p-53 x=[1.0,2.0] y=[3.0,4.0] x+y=[3.9999999999999996,6.000000000000001] x/y=[0.24999999999999997,0.6666666666666667]
Точность и направление округления JInterval задаются глобальным контекстом. По умолчанию округление производится наружу с относительной погрешностью 1.5 младшего разряда формата double. Контекст можно менять, не забывая при этом возвращать его назад, что иллюстрируется следующей программой
package jintervaltutorial;
import com.kenai.jinterval.Interval.RoundingMode;
import com.kenai.jinterval.number.Rational;
import com.kenai.jinterval.rational_bounds.RealInterval;
public class simple {
private static void test() {
System.out.println("test "+RealInterval.currentRoundingMode() + " "+RealInterval.currentRelativeAccuracy());
RealInterval x = RealInterval.valueOf(1.0, 2.0);
RealInterval y = RealInterval.valueOf(3.0, 4.0);
RealInterval s = x.add(y);
RealInterval q = x.divide(y);
System.out.println("x="+x);
System.out.println("y="+y);
System.out.println("x+y="+s);
System.out.println("x/y="+q);
}
private static void testDefault() {
test();
}
private static void testExact() {
RealInterval.enterExactContext();
try {
test();
} finally {
RealInterval.exitContext();
}
}
private static void testFast() {
RealInterval.enterFastContext();
try {
test();
} finally {
RealInterval.exitContext();
}
}
private static void testPrecision(int precision) {
RealInterval.enterContext(RoundingMode.OUTWARDS, Rational.pow2(-precision+1));
try {
test();
} finally {
RealInterval.exitContext();
}
}
public static void main(String[] args) {
testDefault();
testExact();
testFast();
testPrecision(53);
testPrecision(100);
}
}
Её вывод
test OUTWARDS +0x3p-53 x=[1.0,2.0] y=[3.0,4.0] x+y=[3.9999999999999996,6.000000000000001] x/y=[0.24999999999999997,0.6666666666666667] test EXACT +0.0 x=[1.0,2.0] y=[3.0,4.0] x+y=[4.0,6.0] x/y=[0.25,0.6666666666666667] test ANY +0x1p-53 x=[1.0,2.0] y=[3.0,4.0] x+y=[4.0,6.0] x/y=[0.25,0.6666666666666666] test OUTWARDS +0x1p-52 x=[1.0,2.0] y=[3.0,4.0] x+y=[4.0,6.0] x/y=[0.25,0.6666666666666667] test OUTWARDS +0x1p-99 x=[1.0,2.0] y=[3.0,4.0] x+y=[4.0,6.0] x/y=[0.25,0.6666666666666667]
С первого взгляда точность вычислений не увеличивается при увеличении precision. Дело в том, что вывод по умолчанию выдает границы интервала с точностью double. При необходимости можно получить точные границы интервала.
package jintervaltutorial;
import com.kenai.jinterval.Interval.RoundingMode;
import com.kenai.jinterval.number.Rational;
import com.kenai.jinterval.rational_bounds.RealInterval;
public class simple {
private static void test() {
System.out.println("test "+RealInterval.currentRoundingMode() + " "+RealInterval.currentRelativeAccuracy());
RealInterval x = RealInterval.valueOf(1.0, 2.0);
RealInterval y = RealInterval.valueOf(3.0, 4.0);
RealInterval s = x.add(y);
RealInterval q = x.divide(y);
System.out.println("x="+x);
System.out.println("y="+y);
System.out.println("x+y=["+s.exactInf()+","+s.exactSup()+"]="+s);
System.out.println("x/y=["+q.exactInf()+","+q.exactSup()+"]="+q);
}
private static void testDefault() {
test();
}
private static void testExact() {
RealInterval.enterExactContext();
try {
test();
} finally {
RealInterval.exitContext();
}
}
private static void testFast() {
RealInterval.enterFastContext();
try {
test();
} finally {
RealInterval.exitContext();
}
}
private static void testPrecision(int precision) {
RealInterval.enterContext(RoundingMode.OUTWARDS, Rational.pow2(-precision+1));
try {
test();
} finally {
RealInterval.exitContext();
}
}
public static void main(String[] args) {
testDefault();
testExact();
testFast();
testPrecision(53);
testPrecision(100);
}
}
Результат вывода
test OUTWARDS +0x3p-53 x=[1.0,2.0] y=[3.0,4.0] x+y=[+0x1fffffffffffffp-51,+0x18000000000001p-50]=[3.9999999999999996,6.000000000000001] x/y=[+0x1fffffffffffffp-55,+0xaaaaaaaaaaaabp-52]=[0.24999999999999997,0.6666666666666667] test EXACT +0.0 x=[1.0,2.0] y=[3.0,4.0] x+y=[+0x1p2,+0x3p1]=[4.0,6.0] x/y=[+0x1p-2,+0x1/0x3*2^1]=[0.25,0.6666666666666667] test ANY +0x1p-53 x=[1.0,2.0] y=[3.0,4.0] x+y=[+0x1p2,+0x3p1]=[4.0,6.0] x/y=[+0x1p-2,+0x15555555555555p-53]=[0.25,0.6666666666666666] test OUTWARDS +0x1p-52 x=[1.0,2.0] y=[3.0,4.0] x+y=[+0x1p2,+0x3p1]=[4.0,6.0] x/y=[+0x1p-2,+0xaaaaaaaaaaaabp-52]=[0.25,0.6666666666666667] test OUTWARDS +0x1p-99 x=[1.0,2.0] y=[3.0,4.0] x+y=[+0x1p2,+0x3p1]=[4.0,6.0] x/y=[+0x1p-2,+0xaaaaaaaaaaaaaaaaaaaaaaaabp-100]=[0.25,0.6666666666666667]





