将浮点数“>=”转换为“>”,“<=”转换为“<”
Converting floating point ">=" to ">" and "<=" to "<"
我正在 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
该库显然不支持 >= 操作。这在浮点意义上是不实用的。要创建一个等效函数,我需要增加和减少我的比较值来解决这个问题,然后使用大于运算和小于运算。
例如
如果我有一个包含 5 个值 [99.4, 20, 19.9, 99, 80] 的数组,ippsThreshold_LTValGTVal_32s 向量运算将让我用自己的替换值替换向量中的特定值。在此示例中,我想用 0 替换所有 >= 99 和 <= 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 的用途。我希望这些值与原始值之间的差异尽可能小,同时仍然足够重要以将值包含在 > 和 < 操作中。
根据设计,对于 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 := 00000000000001;
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)?
我正在 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
该库显然不支持 >= 操作。这在浮点意义上是不实用的。要创建一个等效函数,我需要增加和减少我的比较值来解决这个问题,然后使用大于运算和小于运算。
例如
如果我有一个包含 5 个值 [99.4, 20, 19.9, 99, 80] 的数组,ippsThreshold_LTValGTVal_32s 向量运算将让我用自己的替换值替换向量中的特定值。在此示例中,我想用 0 替换所有 >= 99 和 <= 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 的用途。我希望这些值与原始值之间的差异尽可能小,同时仍然足够重要以将值包含在 > 和 < 操作中。
根据设计,对于 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 := 00000000000001;
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)?