比较两个double或两个float值的最有效方法是什么?
简单地这样做是不正确的:
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
Run Code Online (Sandbox Code Playgroud)
但是像这样:
bool CompareDoubles2 (double A, double B)
{
diff = A - B;
return (diff < EPSILON) && (-diff < EPSILON);
}
Run Code Online (Sandbox Code Playgroud)
似乎浪费处理.
有谁知道更聪明的浮动比较器?
我有一个单元测试,测试边界:
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void CreateExtent_InvalidTop_ShouldThrowArgumentOutOfRangeException()
{
var invalidTop = 90.0 + Double.Epsilon;
new Extent(invalidTop, 0.0, 0.0, 0.0);
}
public static readonly double MAX_LAT = 90.0;
public Extent(double top, double right, double bottom, double left)
{
if (top > GeoConstants.MAX_LAT)
throw new ArgumentOutOfRangeException("top"); // not hit
}
Run Code Online (Sandbox Code Playgroud)
我以为我只是通过添加最小可能的正双倍来向尖端90.0倾斜,但现在异常没有被抛出,任何想法为什么?
在调试时,我看到top为90,当它应该是90.00000000 ....
编辑:
我应该考虑更难,90+Double.Epsilon将失去其解决方案.似乎最好的方法是做一些转移.
解:
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void CreateExtent_InvalidTop_ShouldThrowArgumentOutOfRangeException()
{
var invalidTop = Utility.IncrementTiny(90); // 90.000000000000014
// var sameAsEpsilon = Utility.IncrementTiny(0);
new Extent(invalidTop, 0, 0, 0);
}
/// <summary> …Run Code Online (Sandbox Code Playgroud) 甲float(又名单个)值是一个4字节的值,并且应该代表任何实值的数.由于它的格式化方式和有限的字节数,它可以表示最小值和最大值,并且它具有有限的精度,具体取决于它自己的值.
我想知道是否有办法在浮点数的有限精度下获得高于或低于某个参考值的最接近的可能值.对于整数,这是微不足道的:只需添加或减去1.但是使用a float,您不能简单地添加或减去最小浮点值并期望它与原始值不同.即
float FindNearestSmaller (const float a)
{
return a - FLT_MIN; /* This doesn't necessarily work */
}
Run Code Online (Sandbox Code Playgroud)
事实上,上述几乎永远不会奏效.在上面的例子中,返回通常仍然相等a,因为FLT_MIN它远远超出了精度a.您可以轻松地自己尝试:它适用于例如0.0f或非常少量的订单FLT_MIN,但不适用于0到100之间的任何订单.
那么在a给定浮点精度的情况下,如何获得最接近但小于或大于的值?
注意:虽然我主要对C/C++答案感兴趣,但我认为答案适用于大多数编程语言.
介绍
对于某些计算,我需要找到可以在指定数字中添加/减去的最小可能数,而不会使内部使用的数据类型出现问题.
目标
我试着编写一个函数,它能够在值DIR的方向上将下一个最接近的数字返回到VALUE.
function nextNearest(value, direction) {
// Special cases for value==0 or value==direction removed
if (direction < value) {
return value - Number.MIN_VALUE;
} else {
return value + Number.MIN_VALUE;
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题是,JavaScript使用64位浮点类型(我认为),它具有不同的最小步长,具体取决于它的当前指数.
问题详细
问题是步长取决于其当前指数:
var a = Number.MIN_VALUE;
console.log(a);
// 5e-324
console.log(a + Number.MIN_VALUE);
// 1e-323 (changed, as expected)
var a = Number.MAX_VALUE;
console.log(a);
// 1.7976931348623157e+308
console.log(a - Number.MIN_VALUE);
// 1.7976931348623157e+308 (that's wrong)
console.log(a - Number.MIN_VALUE == a);
// true (which also is wrong)
Run Code Online (Sandbox Code Playgroud)
摘要
那么我怎样才能找到可以在任何方向上从参数中指定的值加/减的最小可能数?在C++中,通过访问数字二进制值可以很容易地实现这一点.
我正在寻找一种方法在Delphi中获取最小的单浮点值和双浮点值,我可以添加或减去或添加到我的数字,以使浮点数比较的数字不同.或者,如果我可以获得比我的数字更小和更大的下一个浮点数.从浮点的角度来看,我想转换这个:
if (A >= B) or (C <= D) then
Run Code Online (Sandbox Code Playgroud)
至
if (A > newnumber1) or (C < newnumber2) then
Run Code Online (Sandbox Code Playgroud)
它们在浮点产生相同结果的地方.newnumber1和newnumber2显然是用于单和双打不同.我需要一些值,我可以从我的A中减去并添加到我的C值以获得newnumber1和newnumber2,或者我需要一种从B和D获取这些数字的方法.
在C++ 11中,有一个方法std::nextafter在这个问题中引用,看起来就足够了.
上下文
我正在做矢量操作,我需要做相当于大于或等于.实现此目的的最简单方法是采用稍微小一些的数字,并使用大于操作的数字.如果可能的话,我宁愿不要嘲笑似乎有效的价值.
我正在使用的向量操作是ippsThreshold_LTValGTVal_32s来自:
https://software.intel.com/en-us/node/502143
该库显然不支持> =操作.这在浮点意义上是不实际的.要创建一个等效函数,我需要增加和减少我的比较值来计算它,然后使用大于操作和小于操作.
例如
如果我有一个包含5个值的数组[99.4,20,19.9,99,80],ippsThreshold_LTValGTVal_32s向量操作将允许我用我自己的替换值替换向量中的特定值.在这个例子中,我想用0替换所有值> = 99和<= 20.要做到这一点,我想传递这样的东西.因此,我必须用略小的东西替换99,用稍微大一些的东西替换20.
函数签名如下所示:
ippsThreshold_LTValGTVal_32s(..., ..., ..., levelLT, valueLT, levelGT, valueGT);
Run Code Online (Sandbox Code Playgroud)
我的电话会是这样的:
ippsThreshold_LTValGTVal_32s(..., ..., ..., 20.00000001, 0, 98.99999, 0);
Run Code Online (Sandbox Code Playgroud)
然后,这将包括用于小于操作的20和用于大于操作的99,并且给出一个看起来像[0,0,0,0,80]的向量.
我需要找出20.0000001和98.999999的用途.我希望这些值之间的差异和原始值尽可能小,同时仍然足够重要,以包括>和<操作中的值.
algorithm ×1
c ×1
c# ×1
c++ ×1
delphi ×1
delphi-xe4 ×1
double ×1
epsilon ×1
javascript ×1
math ×1
optimization ×1
simd ×1
unit-testing ×1