Hoe integer omzetten om impliciet te verdubbelen?

of ik kan static_castgebruiken. Hoe dan ook, vooral wanneer de formule lang is. Is er een betere oplossing?


Antwoord 1, Autoriteit 100%

U kunt vermenigvuldigen met 1,0:

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

En wanneer u met sommen werkt, kunt u toevoegen aan 0,0:

double d = 0.0 + a - b + c;

De meeste compilers uitvoeren optimalisatie zodanig dat de zinloze bediening niet wordt geëvalueerd. Alleen type conversie is voltooid.


Vergeet niet dat u alleen het eerste lid in elke divisie / vermenigvuldigingsgroep hoeft uit te brengen. Doe dat op een manier die redelijk lijkt. En eenvoudige toevoeging / substractie (met geen ander type multipliers / delers) is ook gegoten. Compilers garanderen gieten. Dus uw voorbeeld:

double d = (double)a / (double)b + (double)c;

kan echt worden herschreven als volgt:

double d = (double)a / b + c;
double d = 1.0 * a / b + c;
double d = static_cast<double>(a) / b + c;

Nog enkele voorbeelden:

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;

Antwoord 2, Autoriteit 21%

Is er een betere oplossing?

Ja. Express-intentie door functies.

Marvel als de optimiser perfect efficiënte assembler uitzendt. Geniet van de onderscheidingen van uw collega’s die in verwondering staren bij uw ontzagbare leesbare en onderhoudbare code:

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

Voor de lol, hier is een oplossing op basis van tuples & amp; Lambdas:

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

… en iets meer leesbaarder …

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

Antwoord 3

Dit werkt, maar alles wat je nodig hebt is een enkele 1.0*voor 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;

De regels van de voorrang en de impliciete conversie zullen ervoor zorgen dat alle variabelen worden omgezet in doubles.

Eén ding om voorzichtig te zijn is gegroepeerde variabelen die hun eigen 1.0*of 0.0+moeten hebben, zoals van toepassing:

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);

afwisselend, gebruik één gebruik een statische cast op de bijbehorende variabele. Ik geef de voorkeur aan de kleinere versie als 1.0*of 0.0+beiden schreeuwen impliciete conversie naar doubles.

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

Other episodes