อะไรคือการคัดเลือกนักแสดงคำสั่งของปฏิบัติการใน arithmetics ใน c++?

0

คำถาม

ทำไมถึงทำ

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

กลับมา int ใน C++และทำไม

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

กลับมา double? โดยเฉพาะทำไมถึงการคัดเลือกนักแสดงหลัง +-ปฏิบัติการเพียงพอที่จะแสดง double. ทำไมมันไม่ต้องการก่อน + หรืออยู่ในตัวเลขโรมันราบเป็นอย่างดีใช่มั๊ยครับ? นี่ static_cast กาเลือกทางของการคัดเลือกนักแสดง?

รหัส:

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

คำตอบที่ดีที่สุด

2

มันไม่มีสิ่งที่เรียกว่า"การคัดเลือกนักแสดงคำสั่ง"เพราะคนประเภทของการแสดงขึ้นอยู่กับมัน operands. วางมันก็แค่ถ้าเป็นเลขฐานสองรวมอัตโนมัติโอเปอเรเตอร์ยอมรับสองคน operands ที่แตกต่างกันประเภทแล้วก็ลดลงประเภทจะ implicitly แปลงไปที่กว้างกประเภท

ใน result = static_cast<double>(1 / (i+1)) มันต่างๆที่วิเคราะห์เหมือนนี้

  • i + 1 เป็ int แสดงตั้งแต่ทั้งสอง i แล้ว 1 เป็นประเภท int
  • 1 / (i + 1) จะคืนค่าเป็น int ได้สำหรับเหตุผลเดียวกับ
  • งั้นผลของ 1 / (i + 1) คือ statically แสดงให้ double

OTOH ใน result = 1 / (i+static_cast<double>(1)) มันเหมือนนี้

  • 1 ได่ถูกต้อง double
  • i + static_cast<double>(1) กลับมา double เพราะว่า i ได่ถูกต้อง double เนื่องจากคนอื่น operand
  • 1 / (i+static_cast<double>(1)) เป็ double สำนวนสำหรับเหตุผลเดียวกับ

แต่ไม่มีใครแสดงแบบนั้น มันจะดีกว่าต้องทำ 1 / (i + 1.0) แทนที่จะเป็น

กฏข้อที่สมบูรณ์แบเป็นแบบนี้

  • ถ้าเหมือนกั operand คนหาข้อมูล enumeration ประเภทไม่มีการแปลงเป็นแสดง:อี operand และกลับประเภทต้องมีคนประเภทเดียวกัน
  • ไม่อย่างนั้นถ้าเหมือนกั operand คือ long doubleอีกคน operand เป็นแปลงไป long double
  • ไม่อย่างนั้นถ้าเหมือนกั operand คือ doubleอีกคน operand เป็นแปลงไป double
  • ไม่อย่างนั้นถ้าเหมือนกั operand คือ floatอีกคน operand เป็นแปลงไป float
  • ไม่เช่นนั้น operand มีจำนวนเต็มประเภท(เพราะ bool, char, char8_t, char16_t, char32_t, wchar_tและ unscoped enumeration ถูกเลื่อนขั้นตอนนี้)และ integral conversions คือสมัครจะผลิตมันเป็นห้องประเภทที่ติดตาม:
    • ถ้าทั้งสอง operands เป็นเซ็นหรือสองอย่างไม่ต้องเซ็นที่ operand กับน้อยกว่าการแปลงตำแหน่งเป็นแปลงไปที่ operand กับคนมากกว่าจำนวนเต็มการแปลงตำแหน่ง
    • ไม่อย่างนั้นถ้าไม่ต้องเซ็น operand เป็น การแปลงตำแหน่ง เป็นมากกว่าหรือเท่ากับการแปลงตำแหน่งของเซ็น operand ที่เซ็น operand เป็นแปลงไปโดยไม่เซ็น operand เป็นแบบนั้น
    • ไม่อย่างนั้นถ้าเซ็น operand เป็นประเภทสามารถเป็นตัวแทนของทั้งค่าต่างๆของโดยไม่เซ็น operand ที่ไม่ต้องเซ็น operand เป็นแปลงไปที่เซ็น operand เป็นประเภท
    • ไม่อย่างนั้นทั้งสอง operands เป็นแปลงไปโดยไม่เซ็นที่เป็นคู่มือของเซ็น operand เป็นแบบนั้น

ใน การแปลงตำแหน่ง อยู่เหนือยิ่งเพิ่มในคำสั่ง bool, signed char, short, int, long, long long. ที่ตำแหน่งของโดยไม่เซ็นประเภทมันจะเท่ากับตำแหน่งของที่สัมพันธ์กันเซ็นต์แบบนั้น ที่ตำแหน่งของ char มันจะเท่ากับตำแหน่งของ signed char แล้ว unsigned char. แบบของ char8_t, char16_t, char32_tแล้ว wchar_t นี่เท่ากับต้นแบบของพวกเขา underlying ยชนิด

รวมอัตโนมัติ operators

2021-11-21 13:34:10

เยี่ยมเลยขอบคุณ! นี่แหละคือคำตอบฉันกำลังมองหา ฉันเจอเคล็ดลับกับอ 1.0 โดยเฉพาะอย่างยิ่งเป็นประโยชน์!
DataFace
1
static_cast<double>(1 / (i+1));

ก่อน 1 / (i+1) ได้ประเมินผล. เพราะว่า 1 คืน int แล้ว i+1 เป็ intดังนั้นนี่คือการหารจำนวนเต็มดังนั้น 1/(i+1) เป็ int. ผลลัพธ์ที่ได้จากนั้ typecast ไป double. ดังนั้นในทางเทคนิค static_cast<double>(1 / (i+1)); จะได้ค่าเป็น doubleแต่ผลลัพธ์ที่ได้สูญเสียเพราะว่า 1/(i+1) คือการหารจำนวนเต็ม

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

ตอนนี้ becuase static_cast<double>(i+1) เป็นสอง, 1 / static_cast<double>(i+1); ตอนนี้ตัวเองลอยเคว้งคว้างจุด divison,ดังนั้น 1 / static_cast<double>(i+1); เป็ double

2021-11-21 13:26:20

และแน่นอน 1.0 /(i + 1) เป็นยิ่งกว่าดีอีก
Pete Becker
1

คุณควรจะรู้เรื่อง จำนวนเต็ม Divison

คุณสามารถใช้รหัสเห็นว่าจริงๆแล้วมันจะได้ค่าเป็นสองเท่า อย่างไรก็ตามเนื่องจากการหารจำนวนเต็มมันจะเป็นศูนย์(หรือ 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;
}

คุณสามารถ circumvent จำนวนเต็มดิวิชั่นโดยไม่ dividing สองคน integers. Therefor มันเป็นเพียงพอถ้าใครคนใดคนหนึ่งของพวกเขาเป็นสองเท่า

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

ดังนั้นคุณสามารถเห็นมันเป็นเพียงพอที่จะแสดงหนึ่ง summand ต้องสองเพื่อเปิดตลอดสำนวนในสองซึ่งมันไม่ตลอดศูนย์ศูนย์ศูนย์

2021-11-21 13:30:50

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

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

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่