Čo je odlievanie poradie operácií v arithmetics v c++?

0

Otázka

Prečo

  1. result = static_cast<double>(1 / (i+1))

návrat int v C++ a prečo

  1. result = 1 / (i+static_cast<double>(1))

návrat double? Konkrétne, prečo je odlievanie po +-prevádzka postačujúce na dosiahnutie double. Prečo nie je potrebné pred + alebo v čitateli aj? Je static_cast preferovaný spôsob casting?

Kód:

double harmonic(int n) {
  double result = 0;
  for (int i = 0; i < n; i++) {
    result += 1 / static_cast<double>(i+1);
  }
  return result;
}
arithmetic-expressions c++ casting types
2021-11-21 13:17:43
3

Najlepšiu odpoveď

2

Nie je tam žiadna taká vec ako "casting objednávku", pretože typ výrazu závisí od jeho operandov. Zjednodušene povedané, ak binárne aritmetický prevádzkovateľ akceptuje dvoch operandov rôznych typov potom menšie typu budú implicitne prevedené do širšieho typ

V result = static_cast<double>(1 / (i+1)) je analyzovaný ako to

  • i + 1 je int termín od oboch i a 1 je typu int
  • 1 / (i + 1) vráti int z rovnakého dôvodu
  • Potom výsledok 1 / (i + 1) je staticky obsadenie double

OTOH v result = 1 / (i+static_cast<double>(1)) je to tak ako to

  • 1 je obsadenie double
  • i + static_cast<double>(1) vráti double pretože i je obsadenie double vzhľadom na druhý operand
  • 1 / (i+static_cast<double>(1)) je double vyjadrenie rovnakého dôvodu

Ale nikto cast páči, že. Je to lepšie robiť 1 / (i + 1.0) namiesto

Kompletné pravidlo je, ako je táto

  • Ak jeden operand má zamerané typ výpočtov, bez konverzie sa vykonáva: druhý operand a návrat typu, musia mať rovnaký typ
  • Inak, ak jeden operand je long double, druhý operand je prevedené na long double
  • Inak, ak jeden operand je double, druhý operand je prevedené na double
  • Inak, ak jeden operand je float, druhý operand je prevedené na float
  • Inak, operand má celé číslo typu (pretože bool, char, char8_t, char16_t, char32_t, wchar_ta unscoped vyčíslenie boli propagované v tomto bode) a neoddeliteľnou konverzie sú použité na výrobu spoločné typ a dopĺňa takto:
    • Ak oboch operandov sú podpísané alebo obaja sú nepodpísané, na operand s menšími konverzie rank je prevedený na operand s vyšším integer konverzie hodnosť
    • Inak, ak nepodpísané operand je konverzie rank je väčšia alebo sa rovná konverzie rank podpísané operand, podpísaná operand je prevedený na nepodpísané operand je typu.
    • Inak, ak podpísané operand je typu môže zastupovať všetkých hodnôt nepodpísané operand, unsigned operand je prevedený do podpísané operand je typu
    • V opačnom prípade oboch operandov sú prevedené do podpísaný exemplár podpísanej operand je typu.

Na prepočet rank nad zvyšuje v poradí bool, signed char, short, int, long, long long. Hodnosť všetky nepodpísané typ je rovná hodnosti zodpovedajúce podpísané typu. Hodnosť char je rovná hodnosti signed char a unsigned char. Hodnosti char8_t, char16_t, char32_ta wchar_t sú rovná hodnosti ich základné typy.

Aritmetické operátory

2021-11-21 13:34:10

Veľká vďaka! Je to presne tak, odpovede, ktoré som hľadala. Našiel som trik s 1.0 obzvlášť užitočné!
DataFace
1
static_cast<double>(1 / (i+1));

Po prvé, 1 / (i+1) získajte vyhodnotenie. Lebo 1 je int a i+1 je inttak toto je celé číslo, oddelenie, tak 1/(i+1) je int. Výsledkom je potom obsadiť do double. Tak technicky, static_cast<double>(1 / (i+1)); vráti double,, ale výsledok je stratené, pretože 1/(i+1) je celočíselné delenie

result += 1 / static_cast<double>(i+1);

Teraz preto, static_cast<double>(i+1) je obojstranný, 1 / static_cast<double>(i+1); je teraz s pohyblivou rádovou čiarkou divison, tak 1 / static_cast<double>(i+1); je double

2021-11-21 13:26:20

A, samozrejme, 1.0 /(i + 1) je ešte lepšie.
Pete Becker
1

Mali by ste si byť vedomí Integer Divison

Môžete použiť tento kód vidieť, že to skutočne vráti dvojnásobne. Avšak, vzhľadom na celočíselné delenie, vždy to bude nula (alebo nan).

#include <iostream>

using std::cout;

int main()
{
    int i = 5;
    cout << typeid(static_cast<double>(1 / (i+1))).name() << "\n"; // d for double
    return 0;
}

Môžete obísť celé divízie, ktoré nie sú deliace dve celé čísla. Ne to je dosť, ak jeden z nich je dvojité.

int + double == double
double + int == double
int / double == double
double / int == double

Takže môžete vidieť, stačí len cast jeden summand na dvojnásobok, s cieľom premeniť celý výraz do dvoch, čo nie je vždy nula.

2021-11-21 13:30:50

V iných jazykoch

Táto stránka je v iných jazykoch

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................