1

短いifelseステートメントのようなものがあります= (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

3つの機能が与えられます:

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
}

結論:

それらはすべてamulsdになりますが、maxsdどのように記述してもかまいません。最も自然で、正しい方法を得るのが最も簡単なものを書くことに時間を費やし、コンパイラにこのような詳細について心配させてください。std::maxあなたがしているのは2つの値のうち大きい方を取っているので、この場合だと思います。

于 2012-05-16T13:32:22.093 に答える