如何隐式地将整数转换为double?

时间:2016-06-12 17:22:13

标签: c++

int a{5},b{2},c{9};
double d = (double)a / (double)b + (double)c;

或者我可以使用static_cast。无论哪种方式都很冗长,特别是当公式很长时。有更好的解决方案吗?

3 个答案:

答案 0 :(得分:6)

可以乘以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 :(得分:3)

  

有更好的解决方案吗?

是。通过功能表达意图。

漫威,因为优化器会发出完美高效的汇编程序。享受同事们的赞誉,他们会惊叹于你那令人难以理解的可读代码:

#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;
}

为了好玩,这里有一个基于元组和解决方案的解决方案。 lambda表达式:

#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;
}

答案 2 :(得分:0)

这可行,但是您所需要的只是在1.0*前面的一个a

int a{5},b{2},c{9};
double d = (double)a / (double)b + (double)c;

int a{5},b{2},c{9};
double d = 1.0*a / b + c;

优先级和隐式转换规则将使所有变量都转换为双精度。

要注意的一件事是分组变量,需要适当使用自己的1.0*0.0+

int a{5},b{2},c{9};
double d = a / (0.0 + b + c);

int a{5},b{2},c{9};
double d = a / (1.0 * b * c);

或者,一种用法是对关联变量使用静态强制转换。我更喜欢较小的版本,因为1.0*0.0+都将隐式转换尖叫为双精度。

int a{5},b{2},c{9};
double d = a / (static_cast<double>(b) * c);