2

Javascript中是否有一个很好的保守区间算术库?

保守的意思是给定两个代表实数范围的区间(其端点恰好是浮点数),它们的区间总和包含原始区间的所有实数总和,对于其他操作也是如此。通过快速搜索找到的唯一库是https://github.com/Jeff-Tian/JavaScriptIntervalArithmetic,但它似乎并不保守。

由于我们无法访问舍入模式,因此如果间隔不是最佳的,那很好(实际上对于速度来说更可取)。例如,如果一个数字的平方保守地近似为 就可以了[(1-epsilon)*(x*x),(1+epsilon)*(x*x)],即使这大于最佳浮点间隔。

4

2 回答 2

3

看看https://github.com/maurizzzio/interval-arithmetic,它的区间代表浮点数,将它与下一个/上一个可以表示的双精度浮点数绑定

var Interval = require('interval-arithmetic');

// { lo: 0.3333333333333333, hi: 0.3333333333333333 }
new Interval().singleton(1 / 3); 

// { lo: 0.33333333333333326, hi: 0.33333333333333337 }
new Interval().boundedSingleton(1 / 3);

类型化数组现在提供了一种方法来处理构成双精度浮点数的字节,库在此处修改此表示的有效位的最后一位,并且所有操作都会保留此舍入误差

于 2015-05-12T18:36:58.487 回答
0

我不太清楚你所说的“保守”是什么意思,但我想添加到Array的原型应该比创建自定义对象更快,你只需要实现你想要的方法。

Array.prototype._interval_plus = function (arr2) {
    return [this[0] + arr2[0], this[1] + arr2[1]];
};
Array.prototype._interval_minus = function (arr2) {
    return [this[0] - arr2[0], this[1] - arr2[1]];
};
Array.prototype._interval_multiply = function (arr2) {
    var ac = this[0] * arr2[0],
        ad = this[0] * arr2[1],
        bc = this[1] * arr2[0],
        bd = this[1] * arr2[1];
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};
Array.prototype._interval_divide = function (arr2) {
    var ac, ad, bc, bd;
    if (arr2[0] === 0 || arr2[1] === 0)
        throw new Error('division by zero');
    ac = this[0] / arr2[0],
    ad = this[0] / arr2[1],
    bc = this[1] / arr2[0],
    bd = this[1] / arr2[1];
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};
Array.prototype._interval_pow = function (arr2, pow) {
    var ac = this[0] * Math.pow(arr2[0], pow),
        ad = this[0] * Math.pow(arr2[1], pow),
        bc = this[1] * Math.pow(arr2[0], pow),
        bd = this[1] * Math.pow(arr2[1], pow);
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};

现在你可以做类似的事情

var x = [ 0  ,  1  ];
    y = [ 0.5,  3.5];
x._interval_plus(y)     // [ 0.5 ,   4.5 ]
 ._interval_multiply(y) // [ 0.25,  15.75]
 ._interval_minus(y)    // [-0.25,  12.25]
 ._interval_pow(y, 2);  // [-3.0625, 150.0625]
于 2014-04-15T02:36:51.227 回答