我正在寻找一种方法在Delphi中获取最小的单浮点值和双浮点值,我可以添加或减去或添加到我的数字,以使浮点数比较的数字不同。或者,如果我可以获得比我的数字更小和更大的下一个浮点数。从浮点的角度来看,我想转换一下:
if (A >= B) or (C <= D) then
要
if (A > newnumber1) or (C < newnumber2) then
它们在浮点数上产生相同的结果。对于单身和双打,newnumber1
和newnumber2
显然会有所不同。我需要一些值,我可以减去我的A并添加到我的C值以获得newnumber1和newnumber2,或者我需要一种从B和D获取这些数字的方法。
在C ++ 11中,有一个方法std::nextafter
在这个问题中引用,看起来就足够了。
Finding the closest floating point value less than a specific integer value in C++?
上下文
我正在做矢量操作,我需要做相当于大于或等于的操作。实现此目的的最简单方法是采用稍微小一些的数字,并使用大于操作的数字。如果可能的话,我宁愿不要嘲笑似乎有效的价值。
我使用的矢量操作是ippsThreshold_LTValGTVal_32s来自:
https://software.intel.com/en-us/node/502143
图书馆显然不支持&gt; =操作。这在浮点意义上是不实际的。要创建一个等效函数,我需要增加和减少我的比较值来计算它,然后使用大于操作和小于操作。
例如
如果我有5个值的数组[99.4,20,19.9,99,80],ippsThreshold_LTValGTVal_32s向量操作将允许我用我自己的替换值替换向量中的特定值。在这个例子中,我想用0替换所有值&gt; = 99和&lt; = 20.要做到这一点,我想传递这样的东西。因此,我必须用略小的东西替换99,而用稍微大一点的东西取代20。
函数签名如下所示:
ippsThreshold_LTValGTVal_32s(..., ..., ..., levelLT, valueLT, levelGT, valueGT);
我的电话会是这样的:
ippsThreshold_LTValGTVal_32s(..., ..., ..., 20.00000001, 0, 98.99999, 0);
然后,这将包括用于小于操作的20和用于大于操作的99,并且给我一个看起来像[0,0,0,0,80]的向量。
我需要找出20.0000001和98.999999的用途。我希望这些值和原始值之间的差异尽可能小,同时仍然足够重要,以包括&gt;中的值。和&lt;操作
答案 0 :(得分:6)
按照设计,对于IEEE754数据类型,您可以简单地将值视为整数并增加该值。如果值为负,则递减它。
function NextDoubleGreater(const D: Double): Double;
var
SpecialType: TFloatSpecial;
I: Int64;
begin
SpecialType := D.SpecialType;
case SpecialType of
fsZero,fsNZero:
// special handling needed around 0 and -0
I := 1;
fsInf, fsNInf, fsNaN:
I := PInt64(@D)^; // return the original value
fsDenormal, fsNDenormal, fsPositive, fsNegative:
begin
I := PInt64(@D)^;
if I >= 0 then begin
inc(I);
end else begin
dec(I);
end;
end;
end;
Result := PDouble(@I)^;
end;
同样在相反的方向:
function NextDoubleLess(const D: Double): Double;
var
SpecialType: TFloatSpecial;
I: Int64;
begin
SpecialType := D.SpecialType;
case SpecialType of
fsZero,fsNZero:
// special handling needed around 0 and -0
I := $8000000000000001;
fsInf, fsNInf, fsNaN:
I := PInt64(@D)^; // return the original value
fsDenormal, fsNDenormal, fsPositive, fsNegative:
begin
I := PInt64(@D)^;
if I >= 0 then begin
dec(I);
end else begin
inc(I);
end;
end;
end;
Result := PDouble(@I)^;
end;
格式是这样的,这并非巧合。由于这种设计,浮点比较运算符的实现是微不足道的。
参考:How to alter a float by its smallest increment (or close to it)?