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

Или я могу использовать static_cast. В любом случае это многословно, особенно когда формула длинная. Есть ли лучшее решение?Как преобразовать целое число в двойное неявно?

+0

Вы протестировали это? Это работает? –

+0

Выберите стиль и будьте последовательны. Двигаться дальше. Если вы сомневаетесь, проверьте список языков ассемблера для всех ваших разных случаев. Выберите наиболее читаемый. –

+1

Приведение к двойному подчеркивает преобразование из int, что хорошо для любого, кто читает код. –

ответ

5

Можно умножать до 1,0:

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. построить тесты производительности на нем или 3. использовать отладчик, чтобы просмотреть сгенерированный код, чтобы его проверить. Я думаю, что старые компиляторы вроде K & R не делают этого, но нынешние разработчики компиляторов хотят быть реальными. – oklas

+7

Переписывание, то, что предназначено для приведения в бессмысленное умножение, является действительно плохим предложением. Если бы я прочитал код, мне пришлось бы остановиться и подумать, проверить историю кода, возможно, удалить ненужное умножение, перекомпилировать, только чтобы узнать, что это должно было быть «static_cast» с самого начала. Не делай этого. Используйте бросок, когда вам нужно конвертировать между типами. – IInspectable

2

Есть ли лучшее решение?

Да. Экспресс-намерение через функции.

Marvel as the optimiser испускает совершенно эффективный ассемблер. Наслаждайтесь почестями ваших коллег, кто смотрит в изумлении на свой грозно читаемый и поддерживаемый коде:

#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

@ Титулум: 'auto' не является типом. Я не могу подчеркнуть это достаточно. –

+0

@LightnessRacesinOrbit Я написал это по привычке. Я не собирался делать заявление. Если вы считаете, что это глупо и вводит в заблуждение, пожалуйста, отредактируйте ответ. –

Смежные вопросы