在 C++ 中使用 min 和 max 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1632145/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use of min and max functions in C++
提问by bporter
From C++, are min
and max
preferable over fmin
and fmax
? For comparing two integers, do they provide basically the same functionality?
从 C++ 来看,是min
并且max
比fmin
和更可取fmax
吗?对于比较两个整数,它们是否提供基本相同的功能?
Do you tend to use one of these sets of functions or do you prefer to write your own (perhaps to improve efficiency, portability, flexibility, etc.)?
您倾向于使用这些函数集之一还是更喜欢编写自己的函数(也许是为了提高效率、可移植性、灵活性等)?
Notes:
笔记:
The C++ Standard Template Library (STL) declares the
min
andmax
functions in the standard C++ algorithmheader.The C standard (C99) provides the
fmin
andfmax
function in the standard C math.hheader.
Thanks in advance!
提前致谢!
回答by Cogwheel
fmin
and fmax
are specifically for use with floating point numbers (hence the "f"). If you use it for ints, you may suffer performance or precision losses due to conversion, function call overhead, etc. depending on your compiler/platform.
fmin
并且fmax
专门用于浮点数(因此是“f”)。如果您将它用于整数,您可能会因转换、函数调用开销等而遭受性能或精度损失,具体取决于您的编译器/平台。
std::min
and std::max
are template functions (defined in header <algorithm>
) which work on any type with a less-than (<
) operator, so they can operate on any data type that allows such a comparison. You can also provide your own comparison function if you don't want it to work off <
.
std::min
和std::max
是模板函数(在 header 中定义),它们可以使用<algorithm>
小于 ( <
) 运算符处理任何类型,因此它们可以对允许进行此类比较的任何数据类型进行操作。如果您不希望它工作,您也可以提供自己的比较功能<
。
This is safer since you have to explicitly convert arguments to match when they have different types. The compiler won't let you accidentally convert a 64-bit int into a 64-bit float, for example. This reason alone should make the templates your default choice. (Credit to Matthieu M & bk1e)
这更安全,因为当参数具有不同类型时,您必须显式转换参数以匹配。例如,编译器不会让您意外地将 64 位 int 转换为 64 位浮点数。仅此原因就应该使模板成为您的默认选择。(归功于 Matthieu M & bk1e)
Even when used with floats the template maywin in performance. A compiler always has the option of inlining calls to template functions since the source code is part of the compilation unit. Sometimes it's impossibleto inline a call to a library function, on the other hand (shared libraries, absence of link-time optimization, etc.).
即使与浮动一起使用,模板也可能在性能上获胜。编译器始终可以选择内联对模板函数的调用,因为源代码是编译单元的一部分。另一方面,有时不可能内联对库函数的调用(共享库、缺少链接时优化等)。
回答by Z boson
There is an important difference between std::min
, std::max
and fmin
and fmax
.
有一个重要区别std::min
,std::max
和fmin
和fmax
。
std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0
whereas
然而
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) = 0.0
So std::min
is not a 1-1 substitute for fmin
. The functions std::min
and std::max
are not commutative. To get the same result with doubles with fmin
and fmax
one should swap the arguments
所以std::min
不是 1-1 的替代品fmin
。函数std::min
和std::max
不是可交换的。要获得与双打相同的结果,fmin
并且fmax
应该交换参数
fmin(-0.0, 0.0) = std::min(-0.0, 0.0)
fmax(-0.0, 0.0) = std::max( 0.0, -0.0)
But as far as I can tell all these functions are implementation defined anyway in this caseso to be 100% sure you have to test how they are implemented.
但据我所知,在这种情况下,所有这些函数都是实现定义的,因此要 100% 确定您必须测试它们是如何实现的。
There is another important difference. For x ! = NaN
:
还有一个重要的区别。对于x ! = NaN
:
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x
whereas
然而
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x
fmax
can be emulated with the following code
fmax
可以用下面的代码模拟
double myfmax(double x, double y)
{
// z > nan for z != nan is required by C the standard
int xnan = isnan(x), ynan = isnan(y);
if(xnan || ynan) {
if(xnan && !ynan) return y;
if(!xnan && ynan) return x;
return x;
}
// +0 > -0 is preferred by C the standard
if(x==0 && y==0) {
int xs = signbit(x), ys = signbit(y);
if(xs && !ys) return y;
if(!xs && ys) return x;
return x;
}
return std::max(x,y);
}
This shows that std::max
is a subset of fmax
.
这表明std::max
是 的子集fmax
。
Looking at the assembly shows that Clang uses builtin code for fmax
and fmin
whereas GCC calls them from a math library. The assembly for clang for fmax
with -O3
is
查看程序集显示 Clang 使用内置代码fmax
,fmin
而 GCC 从数学库调用它们。clang for fmax
with的程序集-O3
是
movapd xmm2, xmm0
cmpunordsd xmm2, xmm2
movapd xmm3, xmm2
andpd xmm3, xmm1
maxsd xmm1, xmm0
andnpd xmm2, xmm1
orpd xmm2, xmm3
movapd xmm0, xmm2
whereas for std::max(double, double)
it is simply
而因为std::max(double, double)
它只是
maxsd xmm0, xmm1
However, for GCC and Clang using -Ofast
fmax
becomes simply
但是,对于 GCC 和 Clang 使用-Ofast
fmax
变得简单
maxsd xmm0, xmm1
So this shows once again that std::max
is a subset of fmax
and that when you use a looser floating point model which does not have nan
or signed zero then fmax
and std::max
are the same. The same argument obviously applies to fmin
and std::min
.
所以这再次表明这std::max
是一个子集fmax
,当你使用一个更松散的浮点模型时,它没有nan
或没有符号零,fmax
并且std::max
是相同的。同样的论点显然适用于fmin
和std::min
。
回答by J Ridges
You're missing the entire point of fmin and fmax. It was included in C99 so that modern CPUs could use their native (read SSE) instructions for floating point min and max and avoid a test and branch (and thus a possibly mis-predicted branch). I've re-written code that used std::min and std::max to use SSE intrinsics for min and max in inner loops instead and the speed-up was significant.
您错过了 fmin 和 fmax 的全部内容。它包含在 C99 中,以便现代 CPU 可以使用其原生(读取 SSE)指令进行浮点最小值和最大值,并避免测试和分支(因此可能是错误预测的分支)。我已经重新编写了使用 std::min 和 std::max 的代码,以在内部循环中使用 SSE 内在函数的 min 和 max ,并且加速非常显着。
回答by sellibitze
std::min and std::max are templates. So, they can be used on a variety of types that provide the less than operator, including floats, doubles, long doubles. So, if you wanted to write generic C++ code you'd do something like this:
std::min 和 std::max 是模板。因此,它们可用于提供小于运算符的各种类型,包括浮点数、双精度数、长双精度数。因此,如果您想编写通用的 C++ 代码,您可以这样做:
template<typename T>
T const& max3(T const& a, T const& b, T const& c)
{
using std::max;
return max(max(a,b),c); // non-qualified max allows ADL
}
As for performance, I don't think fmin
and fmax
differ from their C++ counterparts.
至于性能,我不认为fmin
和fmax
他们的 C++ 同行不同。
回答by Jerry Coffin
If your implementation provides a 64-bit integer type, you may get a different (incorrect) answer by using fmin or fmax. Your 64-bit integers will be converted to doubles, which will (at least usually) have a significand that's smaller than 64-bits. When you convert such a number to a double, some of the least significant bits can/will be lost completely.
如果您的实现提供 64 位整数类型,您可能会通过使用 fmin 或 fmax 得到不同(不正确)的答案。您的 64 位整数将转换为双精度数,这将(至少通常)具有小于 64 位的有效数。当您将这样的数字转换为双精度数时,一些最低有效位可能/将完全丢失。
This means that two numbers that were really different could end up equal when converted to double -- and the result will be that incorrect number, that's not necessarily equal to either of the original inputs.
这意味着两个真正不同的数字在转换为 double 时最终可能相等——结果将是那个不正确的数字,它不一定等于原始输入中的任何一个。
回答by Eric Melski
I would prefer the C++ min/max functions, if you are using C++, because they are type-specific. fmin/fmax will force everything to be converted to/from floating point.
如果您使用 C++,我更喜欢 C++ min/max 函数,因为它们是特定于类型的。fmin/fmax 将强制将所有内容转换为浮点数/从浮点数转换。
Also, the C++ min/max functions will work with user-defined types as long as you have defined operator< for those types.
此外,只要您为这些类型定义了 operator<,C++ min/max 函数就可以使用用户定义的类型。
HTH
HTH
回答by AnT
As you noted yourself, fmin
and fmax
were introduced in C99. Standard C++ library doesn't have fmin
and fmax
functions. Until C99 standard library gets incorporated into C++ (if ever), the application areas of these functions are cleanly separated. There's no situation where you might have to "prefer" one over the other.
正如您自己指出的那样,fmin
并且fmax
是在 C99 中引入的。标准 C++ 库没有fmin
和fmax
函数。在 C99 标准库被并入 C++(如果有的话)之前,这些函数的应用领域是完全分开的。在任何情况下,您都可能不得不“偏爱”一个而不是另一个。
You just use templated std::min
/std::max
in C++, and use whatever is available in C.
您只需在 C++ 中使用模板化std::min
/ std::max
,并使用 C 中可用的任何内容。
回答by mloskot
As Richard Corden pointed, use C++ functions min and max defined in std namespace. They provide type safety, and help to avoid comparing mixed types (i.e. float point vs integer) what sometimes may be undesirable.
正如 Richard Corden 所指出的,使用 std 命名空间中定义的 C++ 函数 min 和 max。它们提供类型安全,并有助于避免比较混合类型(即浮点与整数)有时可能是不受欢迎的。
If you find that C++ library you use defines min/max as macros as well, it may cause conflicts, then you can prevent unwanted macro substitution calling the min/max functions this way (notice extra brackets):
如果你发现你使用的 C++ 库也将 min/max 定义为宏,它可能会导致冲突,那么你可以防止不需要的宏替换以这种方式调用 min/max 函数(注意额外的括号):
(std::min)(x, y)
(std::max)(x, y)
Remember, this will effectively disable Argument Dependant Lookup(ADL, also called Koenig lookup), in case you want to rely on ADL.
请记住,这将有效地禁用参数相关查找(ADL,也称为 Koenig 查找),以防您想依赖 ADL。
回答by user3405743
Couldn't a C++ implementation targeted for processors with SSE instructions provide specializations of std::minand std::maxfor types float, double, and long doublewhich do the equivalent of fminf, fmin, and fminl, respectively?
针对具有 SSE 指令的处理器的 C++ 实现不能为float、double和long double类型提供std::min和std::max 的特化,它们分别相当于fminf、fmin和fminl吗?
The specializations would provide better performance for floating-point types while the general template would handle non-floating-point types without attempting to coerce floating-point types into floating-point types that way the fmins and fmaxes would.
特化将为浮点类型提供更好的性能,而通用模板将处理非浮点类型,而不会像fmins 和fmaxes 那样试图将浮点类型强制转换为浮点类型。
回答by Richard Corden
Use std::min
and std::max
.
使用std::min
和std::max
。
If the other versions are faster then your implementation can add overloads for these and you'll get the benefit of performance and portability:
如果其他版本更快,那么您的实现可以为这些添加重载,您将获得性能和可移植性的好处:
template <typename T>
T min (T, T) {
// ... default
}
inline float min (float f1, float f2) {
return fmin( f1, f2);
}