int a{5},b{2},c{9};
double d = (double)a/(double)b + (double)c;
またはstatic_cast
を使用できます。どちらの方法も冗長で、特に数式が長い場合は冗長です。より良い解決策はありますか?整数を暗黙的に倍精度に変換する方法は?
int a{5},b{2},c{9};
double d = (double)a/(double)b + (double)c;
またはstatic_cast
を使用できます。どちらの方法も冗長で、特に数式が長い場合は冗長です。より良い解決策はありますか?整数を暗黙的に倍精度に変換する方法は?
:
int a{5},b{2},c{9};
double d = 1.0 * a/b + 1.0 * c;
そして、あなたは0.0を使用することが可能合計で作業:
double d = 0.0 + a - b + c;
ほとんどのコンパイラは最適化と、本当にこのような操作を行うことが評価されません。タイプ変換のみが行われます。
各除算/乗算グループに最初のメンバーのみをキャストする必要があることに注意してください。どんなソリューションでもあなたには何が好きですか?また、単純な加算/減算(別の型乗数/除算器を持たない)もキャストされました。コンパイラはキャストを保証します。だからあなたの例:
double d = (double)a/(double)b + (double)c;
本当にこれの一つとして書き換え中することができる。
double d = (double)a/b + c;
double d = 1.0 * a/b + c;
double d = static_cast<double>(a)/b + c;
ただ、より多くの例:
double d = (double)a/b + (double)c/d + e;
double d = 1.0 * a/b + 1.0 * c/d + e;
double d = static_cast<double>(a)/b + static_cast<double>(c)/d + e;
疑問がある場合(「ほとんどのコンパイラ」)、あなたはそれを行うべきではありません。 –
誰かがこのような細部を懸念したときには、1.ターゲットコンパイラマニュアルを読んだり、2.性能テストをビルドしたり、デバッガを使って生成コードを慎重に確認してください。私はK&Rのような古いコンパイラはこれをしない可能性があると思うが、現在のコンパイラ開発者は実際にしたい。 – oklas
書き直し、無意味な乗算へのキャストを意味するものは、実際には貧弱な提案です。もし私がコードを読んでいたら、コードの履歴を調べて、考え直し、おそらく無駄な乗算を取り除いて再コンパイルして、最初から 'static_cast'だったはずです。これをしないでください。タイプ間の変換が必要な場合は、キャストを使用します。 – IInspectable
は、よりよい解決策はありますか?
はい。関数を介して意図を表現する。
オプティマイザとしてMarvelが完璧に効率的なアセンブラを発行します。あなたの上空で読みやすく、保守し、コードで不思議に見つめる同僚の称賛をお楽しみください:楽しみのために
#include <iostream>
auto a_over_b_plus_c(double a, double b, double c)
{
double d = a/b + c;
return d;
}
int main()
{
int a = 5, b = 2, c = 9;
std::cout << a_over_b_plus_c(a, b, c) << std::endl;
}
を、ここではタプル&ラムダに基づくソリューションです:
#include <iostream>
#include <tuple>
template<class T, class...Args>
auto to(Args&&...args)
{
return std::make_tuple(T(std::forward<Args>(args))...);
}
int main()
{
int a = 5, b = 2, c = 9;
auto calc = [](auto&& vals) {
auto& a = std::get<0>(vals);
auto& b = std::get<1>(vals);
auto& c = std::get<2>(vals);
return a/b + c;
};
auto result = calc(to<double>(a, b, c));
std::cout << result << std::endl;
}
は...と、おそらく何か読みやすい...
#include <iostream>
#include <tuple>
#include <complex>
template<class T, class F, class...Args>
auto with(F f, Args&&...args)
{
return f(T(std::forward<Args>(args))...);
}
int main()
{
int a = 5, b = 2, c = 9;
auto calc = [](auto&& a, auto&& b, auto&& c) {
return a/b + c;
};
auto result = with<double>(calc, a, b, c);
auto result2 = with<float>(calc, a, b, c);
auto result3 = with<std::complex<double>>(calc, a, b, c);
auto result4 = with<std::complex<float>>(calc, a, b, c);
std::cout << result << std::endl;
std::cout << result2 << std::endl;
std::cout << result3 << std::endl;
}
私を 'auto' return型に紹介してくれてありがとう! – Titulum
@Titulum: 'auto'は型ではありません。私は十分にこれを強調することはできません。 –
@ LightnessRacesinOrbit私はそれを習慣から書いた。私は声明を出すつもりはなかった。それがばかげて誤解を招くと思われる場合は、ぜひ回答を編集してください。 –
これはテストしましたか?それは動作しますか? –
スタイルを選択して一貫性を保つ。進む。疑わしいときは、アセンブリー言語のリストを調べて、すべての異なるケースを確認してください。最も読みやすいものを選んでください。 –
doubleをキャストすると、intからの変換が強調されます。これはコードを読む人にとっては役に立ちます。 –