首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C++中使用min和max函数

在C++中使用min和max函数
EN

Stack Overflow用户
提问于 2009-10-28 00:43:02
回答 14查看 311.9K关注 0票数 81

在C++中,std::minstd::maxfminfmax更可取吗?对于比较两个整数,它们是否提供了基本相同的功能?

您是倾向于使用这些函数中的一个,还是更喜欢编写自己的函数(可能是为了提高效率、可移植性、灵活性等)?

备注:

  1. C++标准模板库在标准的C++ algorithm头文件中声明minmax函数。

  1. C标准(C99)在标准C math.h标头中提供了fminfmax函数。

提前感谢!

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2009-10-28 00:47:40

fminfmax专门用于浮点数(因此使用"f")。如果您将它用于int,您可能会因为转换、函数调用开销等而遭受性能或精度损失,这取决于您的编译器/平台。

std::minstd::max是模板函数(在header 中定义),它们使用小于(<)运算符对任何类型进行操作,因此它们可以对允许进行这种比较的任何数据类型进行操作。如果您不想在<上工作,也可以提供自己的比较函数。

这更安全,因为当参数具有不同的类型时,您必须显式转换参数以匹配它们。例如,编译器不会让您意外地将64位int转换为64位浮点型。仅此原因就应该使模板成为您的默认选择。(归功于Matthieu M& bk1e)

即使与浮点数一起使用,模板也可能在性能上赢得。编译器总是可以选择内联对模板函数的调用,因为源代码是编译单元的一部分。另一方面,有时不可能内联对库函数的调用(共享库,缺少链接时优化,等等)。

票数 118
EN

Stack Overflow用户

发布于 2015-06-18 20:22:27

std::minstd::maxfminfmax之间有一个重要的区别。

代码语言:javascript
运行
复制
std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0

鉴于

代码语言:javascript
运行
复制
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) =  0.0

因此,std::min不是fmin的1:1替代品。函数std::minstd::max是不可交换的。要获得与fminfmax的doubles相同的结果,应该交换参数

代码语言:javascript
运行
复制
fmin(-0.0, 0.0) = std::min(-0.0,  0.0)
fmax(-0.0, 0.0) = std::max( 0.0, -0.0)

但就我所能告诉all these functions are implementation defined anyway in this case的是,要100%确定你必须测试它们是如何实现的。

还有另一个重要的区别。对于x ! = NaN

代码语言:javascript
运行
复制
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x

鉴于

代码语言:javascript
运行
复制
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x

可以用以下代码模拟fmax

代码语言:javascript
运行
复制
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);
}

这表明std::maxfmax的一个子集。

查看程序集可以看到,Clang为fmaxfmin使用了内置代码,而GCC则从一个数学库中调用它们。用于带有-O3fmax的clang程序集为

代码语言:javascript
运行
复制
movapd  xmm2, xmm0
cmpunordsd      xmm2, xmm2
movapd  xmm3, xmm2
andpd   xmm3, xmm1
maxsd   xmm1, xmm0
andnpd  xmm2, xmm1
orpd    xmm2, xmm3
movapd  xmm0, xmm2

而对于std::max(double, double),它只是简单地

代码语言:javascript
运行
复制
maxsd   xmm0, xmm1

然而,对于GCC和克朗来说,使用-Ofast fmax变得很简单

代码语言:javascript
运行
复制
maxsd   xmm0, xmm1

因此,这再次表明std::maxfmax的子集,并且当您使用没有nan或带符号0的松散浮点模型时,fmaxstd::max是相同的。显然,同样的论点也适用于fminstd::min

票数 45
EN

Stack Overflow用户

发布于 2010-11-02 00:35:44

您错过了fmin和fmax的全部要点。它被包括在C99中,以便现代CPU可以使用它们的本机(读取SSE)指令来处理浮点最小和最大浮点,并避免测试和分支(因此可能会预测错误的分支)。我重写了使用std::min和std::max的代码,以便在内部循环中使用SSE内部函数作为min和max,加速效果非常显著。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1632145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档