2016-06-12 14 views
3
int a{5},b{2},c{9}; 
double d = (double)a/(double)b + (double)c; 

またはstatic_castを使用できます。どちらの方法も冗長で、特に数式が長い場合は冗長です。より良い解決策はありますか?整数を暗黙的に倍精度に変換する方法は?

1.0に乗算することが可能に
+0

これはテストしましたか?それは動作しますか? –

+0

スタイルを選択して一貫性を保つ。進む。疑わしいときは、アセンブリー言語のリストを調べて、すべての異なるケースを確認してください。最も読みやすいものを選んでください。 –

+1

doubleをキャストすると、intからの変換が強調されます。これはコードを読む人にとっては役に立ちます。 –

答えて

5

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

疑問がある場合(「ほとんどのコンパイラ」)、あなたはそれを行うべきではありません。 –

+0

誰かがこのような細部を懸念したときには、1.ターゲットコンパイラマニュアルを読んだり、2.性能テストをビルドしたり、デバッガを使って生成コードを慎重に確認してください。私はK&Rのような古いコンパイラはこれをしない可能性があると思うが、現在のコンパイラ開発者は実際にしたい。 – oklas

+7

書き直し、無意味な乗算へのキャストを意味するものは、実際には貧弱な提案です。もし私がコードを読んでいたら、コードの履歴を調べて、考え直し、おそらく無駄な乗算を取り除いて再コンパイルして、最初から 'static_cast'だったはずです。これをしないでください。タイプ間の変換が必要な場合は、キャストを使用します。 – IInspectable

2

は、よりよい解決策はありますか?

はい。関数を介して意図を表現する。

オプティマイザとして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; 
} 
+1

私を 'auto' return型に紹介してくれてありがとう! – Titulum

+3

@Titulum: 'auto'は型ではありません。私は十分にこれを強調することはできません。 –

+0

@ LightnessRacesinOrbit私はそれを習慣から書いた。私は声明を出すつもりはなかった。それがばかげて誤解を招くと思われる場合は、ぜひ回答を編集してください。 –

関連する問題