gpt4 book ai didi

JavaScript。尽可能少地增加或减少 float

转载 作者:行者123 更新时间:2023-11-29 16:38:59 25 4
gpt4 key购买 nike

在javascipt中我有一个像这样的浮点“a”:

var a = 5.;

现在我想要一个新的数字“b”,它只比“a”大一点。我可以这样做:

var b = a + 1.e-10;

但是如果“a”是一个非常小的数字怎么办?

var a = 5.e-20;
var b = a + 1.e-10;

现在“b”比“a”大多个数量级。
另外,如果我将“a”和“b”之间的差异设置得太小,则较大的“a”可能会导致差异被四舍五入。

如何使数字“b”大于任何数字“a”,但比任何其他大于“a”的数字更接近“a”,或者如何使数字“b”为小于“a”,但比任何其他小于“a”的数字更接近“a”。

编辑:
更具体一点:我正在寻找一个函数“makeLarger(a)”,它接受一个数字“a”并返回一个数字“b”,其中“b>a”将始终评估为true,而“c>a && c”对于任何数字“c”,

最佳答案

假设 a 是正数、实数并且远离次正规(在本例中,大于 1.0020841800044864e-292),那么以下应该有效:

var u = Number.EPSILON/2 + Number.EPSILON*Number.EPSILON;
var b = a + a*u;

请注意,b = a * (1+u) 不会工作。 (例如,如果a = 0.9999999999999998)。

基本思想是 float 之间的差距大致成正比,但只会逐步增加(对于同一个 binade 中的所有数字都是相同的)。因此,挑战在于选择足够小的 u,以便它适用于每个二进制的极端情况。

因此,不失一般性,考虑区间 [1.0,2.0) 中的数字 a 就足够了。我们需要确保

Machine.EPSILON/2 < a*u < Machine.EPSILON*3/2

这样最终的加法将按正确的方向舍入(而不是返回到 a 或 2 增量)。可以相当简单地证明上面定义的 u 满足这些属性。

要向下走,你可以这样做

var c = a - a*u;

P.S.:另一种选择,虽然更难证明,是

var v = 1 - Machine.EPSILON/2;
var b = a / v; # upwards
var c = a * v; # downwards

这具有适用于更大范围(任何正的、非次正规实数)的优点。

对于次正规数,您只需添加/减去 Number.MIN_VALUE,因此将它们组合在一起即可得到:

function nextup(a) {
var v = 1 - Number.EPSILON/2;
if (a >= Number.MIN_VALUE / Number.EPSILON) {
// positive normal
return (a/v);
} else if (a > -Number.MIN_VALUE / Number.EPSILON) {
// subnormal or zero
return (a+Number.MIN_VALUE);
} else {
// negative normal or NaN
return (a*v);
}
}

function nextdown(a) {
var v = 1 - Number.EPSILON/2;
if (a >= Number.MIN_VALUE / Number.EPSILON) {
// positive normal
return (a*v);
} else if (a > -Number.MIN_VALUE / Number.EPSILON) {
// subnormal or zero
return (a-Number.MIN_VALUE);
} else {
// negative normal or NaN
return (a/v);
}
}

关于JavaScript。尽可能少地增加或减少 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48330463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com