Building Abstractions with Data - Introduction to Data Abstraction - Extended Exercise: Interval Arithmetic - tolerance, uncertain number
Structure and Interpretation of Computer Programs: JavaScript Edition(Harold Abelson(著)、Gerald Jay Sussman(著)、Julie Sussman(著)、The MIT Press)のChapter 2(Building Abstractions with Data)、2.1(Introduction to Data Abstraction)、2.1.4(Extended Exercise: Interval Arithmetic)、Exercise 2.15解答を求めてみる。
コード
function math_abs(x) {
return Math.abs(x);
}
function display(x) {
return console.log(x);
}
function pair(x, y) {
return [x, y];
}
function head(z) {
return z[0];
}
function tail(z) {
return z[1];
}
function make_interval(x, y) {
return pair(x, y);
}
function lower_bound(i) {
return head(i);
}
function upper_bound(i) {
return tail(i);
}
function make_center_percent(c, p) {
const w = math_abs(c) * p / 100;
return make_interval(c - w, c + w);
}
function center(i) {
return (lower_bound(i) + upper_bound(i)) / 2;
}
function percent(i) {
const u = upper_bound(i);
const m = center(i);
return (u - m) / m * 100;
}
function add_interval(x, y) {
return make_interval(
lower_bound(x) + lower_bound(y),
upper_bound(x) + upper_bound(y)
);
}
function mul_interval(x, y) {
const xl = lower_bound(x);
const xu = upper_bound(x);
const yl = lower_bound(y);
const yu = upper_bound(y);
if (xl < 0) {
if (xu < 0) {
if (yl < 0) {
if (yu < 0) {
return make_interval(xu * yu, xl * yl);
}
return make_interval(xl * yu, xl * yl);
}
return make_interval(xl * yu, xu * yl);
}
if (yl < 0) {
if (yu < 0) {
return make_interval(xu * yl, xl * yl);
}
const p1 = xl * yu;
const p2 = xu * yl;
const p3 = xl * yl;
const p4 = xu * yu;
return make_interval(
math_min(p1, p2),
math_max(p3, p4)
)
}
return make_interval(xl * yu, xu * yu);
}
if (yl < 0) {
if (yu < 0) {
return make_interval(xu * yl, xl * yu);
}
return make_interval(xu * yl, xu * yu);
}
return make_interval(xl * yl, xu * yu);
}
function div_interval(x, y) {
return mul_interval(
x,
make_interval(
1 / upper_bound(y),
1 / lower_bound(y)
)
);
}
function par1(r1, r2) {
return div_interval(
mul_interval(r1, r2),
add_interval(r1, r2)
);
}
function par2(r1, r2) {
const one = make_interval(1, 1);
return div_interval(
one,
add_interval(
div_interval(one, r1),
div_interval(one, r2)
)
);
}
const interval = make_center_percent(100, 1);
const p1 = par1(interval, interval);
const p2 = par2(interval, interval);
display(interval);
display(p1);
display(par1(p1, p1));
display(p2);
display(par2(p2, p2));
入出力結果(Terminal, Zsh)
% node answer2.15.js
[ 99, 101 ]
[ 48.51980198019802, 51.52020202020203 ]
[ 22.847068643815813, 27.353071404595994 ]
[ 49.49999999999999, 50.5 ]
[ 24.749999999999996, 25.25 ]
%