1

是否有类似简短的 if else= (cond) ? true : false语句,但是将条件的结果传递给{ }?或者也许其他一些想法如何编写这种代码更优雅?

double t_day = day * 0.15;
if (t_day < 1) { t_day = 1; }

也许像

double t_day = (day * 0.15) ? day * 0.15 : 1;

但没有额外的计算?

4

2 回答 2

16
double t_day = std::max(day * 0.15, 1.);

不要忘记 之后的句点,1因为编译器将无法推断出正确的double模板参数(最终会出现奇怪的编译器错误)。

于 2012-05-16T13:21:07.640 回答
8

给定三个函数:

double func1(const double& day) {
  double t_day = day * 0.15;
  if (t_day < 1) { t_day = 1; }
  return t_day;
}

double func2(const double& day) {
  return std::max(day*0.15, 1.);
}

double func3(const double& day) {
  return (day * 0.15 > 1) ? day * 0.15 : 1;
}

我们可以检查编译器的输出(例如g++ -O3 -S):

func1变成:

_Z5func1RKd:
.LFB368:
        .cfi_startproc
        movsd   .LC1(%rip), %xmm0
        movsd   .LC0(%rip), %xmm1
        mulsd   (%rdi), %xmm0
        maxsd   %xmm0, %xmm1
        movapd  %xmm1, %xmm0
        ret

func2变成:

_Z5func2RKd:
.LFB370:
        .cfi_startproc
        movsd   .LC1(%rip), %xmm0
        movsd   .LC0(%rip), %xmm1
        mulsd   (%rdi), %xmm0
        maxsd   %xmm0, %xmm1
        movapd  %xmm1, %xmm0
        ret

func3变成:

_Z5func3RKd:
.LFB369:
        .cfi_startproc
        movsd   .LC1(%rip), %xmm0
        mulsd   (%rdi), %xmm0
        maxsd   .LC0(%rip), %xmm0
        ret

其中 LC0 和 LC1 是常数 1.0 和 0.15。

作为参考,Clang 的中间表示可能更容易阅读:

define double @_Z5func1RKd(double* nocapture %day) nounwind uwtable readonly {
  %1 = load double* %day, align 8, !tbaa !0
  %2 = fmul double %1, 1.500000e-01
  %3 = fcmp olt double %2, 1.000000e+00
  %t_day.0 = select i1 %3, double 1.000000e+00, double %2
  ret double %t_day.0
}

define double @_Z5func2RKd(double* nocapture %day) nounwind uwtable readonly {
  %1 = load double* %day, align 8, !tbaa !0
  %2 = fmul double %1, 1.500000e-01
  %3 = fcmp olt double %2, 1.000000e+00
  %4 = select i1 %3, double 1.000000e+00, double %2
  ret double %4
}

define double @_Z5func3RKd(double* nocapture %day) nounwind uwtable readonly {
  %1 = load double* %day, align 8, !tbaa !0
  %2 = fmul double %1, 1.500000e-01
  %3 = fcmp ogt double %2, 1.000000e+00
  %4 = select i1 %3, double %2, double 1.000000e+00
  ret double %4
}

结论:

他们都变成了一个mulsdmaxsd无论你怎么写。花时间以最自然,最容易获得正确的方式编写东西,让编译器担心这样的细节。我会说是std::max在这种情况下,因为您正在做的是取两个值中的较大者。

于 2012-05-16T13:32:22.093 回答