ช่วงของค่าชนิดจำนวนเต็มสามารถจัดเก็บใน C ++ ได้


86

สามารถunsigned long intเก็บตัวเลขหลักสิบ (1,000,000,000 - 9,999,999,999) บนคอมพิวเตอร์ 32 บิตได้หรือไม่?

นอกจากนี้สิ่งที่เป็นช่วงของunsigned long int, long int, unsigned int, short int, short unsigned intและint?

คำตอบ:


139

ขั้นต่ำช่วงที่คุณสามารถพึ่งพา ได้แก่ :

  • short intและint: -32,767 ถึง 32,767
  • unsigned short intและunsigned int: 0 ถึง 65,535
  • long int: -2,147,483,647 ถึง 2,147,483,647
  • unsigned long int: 0 ถึง 4,294,967,295

ซึ่งหมายความว่าไม่ไม่long int สามารถใช้เพื่อจัดเก็บตัวเลข 10 หลักได้ อย่างไรก็ตามประเภทที่ใหญ่กว่าlong long intได้รับการแนะนำให้รู้จักกับ C ใน C99 และ C ++ ใน C ++ 11 (ประเภทนี้มักได้รับการสนับสนุนเป็นส่วนขยายโดยคอมไพเลอร์ที่สร้างขึ้นสำหรับมาตรฐานรุ่นเก่าที่ไม่ได้รวมไว้ด้วย) ช่วงต่ำสุดสำหรับประเภทนี้หากคอมไพเลอร์ของคุณรองรับคือ:

  • long long int: -9,223,372,036,854,775,807 ถึง 9,223,372,036,854,775,807
  • unsigned long long int: 0 ถึง 18,446,744,073,709,551,615

ดังนั้นประเภทนั้นจะใหญ่พอ (อีกครั้งถ้าคุณมี)


หมายเหตุสำหรับผู้ที่เชื่อว่าฉันทำผิดพลาดกับขอบเขตล่างเหล่านี้ - ฉันไม่ได้ทำ ข้อกำหนด C สำหรับช่วงถูกเขียนขึ้นเพื่ออนุญาตให้มีการแสดงจำนวนเต็มส่วนเติมเต็มหรือขนาดเครื่องหมายโดยที่ค่าที่แสดงได้ต่ำสุดและค่าที่แสดงได้สูงสุดจะแตกต่างกันในเครื่องหมาย นอกจากนี้ยังได้รับอนุญาตให้มีการแทนค่าสองส่วนโดยที่ค่าที่มีเครื่องหมายบิต 1 และบิตค่าทั้งหมด 0 เป็นการแสดงกับดักแทนที่จะเป็นค่าทางกฎหมาย กล่าวอีกนัยหนึ่งintคือไม่จำเป็นต้องสามารถแทนค่า -32,768 ได้


ชื่อเดิมว่า "C / C ++" ด้วย
คาเฟ่

ทำไม long long int positive range == ช่วงลบ
mohamed abdallah

1
@mohamedabdallah: ดูย่อหน้าสุดท้ายของคำตอบ: ช่วงมาตรฐาน C เป็นวิธีที่อนุญาตให้มีการแสดงองค์ประกอบเสริมหรือขนาดเครื่องหมาย
คาเฟ่

Aha..I ตระหนักว่าหมายถึงint long int
mazend

32

ขนาดของประเภทตัวเลขไม่ได้กำหนดไว้ในมาตรฐาน C ++ แม้ว่าขนาดต่ำสุดคือ วิธีบอกขนาดที่พวกเขาอยู่บนแพลตฟอร์มของคุณคือการใช้ขีด จำกัด ตัวเลข

ตัวอย่างเช่นค่าสูงสุดสำหรับ int สามารถพบได้โดย:

std::numeric_limits<int>::max();

คอมพิวเตอร์ไม่ทำงานในฐาน 10 ซึ่งหมายความว่าค่าสูงสุดจะอยู่ในรูปของ 2 n -1 เนื่องจากจำนวนตัวแทนในหน่วยความจำ ยกตัวอย่างเช่นแปดบิต (1 ไบต์)

  0100 1000

บิตที่เหมาะสมที่สุด (ตัวเลข) เมื่อตั้งค่าเป็น 1 หมายถึง 2 0 , บิตถัดไป 2 1แล้ว 2 2และอื่น ๆ จนกว่าเราจะได้ไปทางซ้ายเล็กน้อยมากที่สุดซึ่งถ้าจำนวนเป็นไม่ได้ลงนามหมายถึง 2 7

ดังนั้นตัวเลขจึงแทน 2 6 + 2 3 = 64 + 8 = 72 เนื่องจากบิตที่ 4 จากด้านขวาและบิตที่ 7 ทางด้านซ้ายถูกตั้งค่าไว้

หากเราตั้งค่าทั้งหมดเป็น 1:

11111111

ตอนนี้หมายเลข (สมมติว่าไม่ได้ลงนาม )
128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 = 2 8 - 1
และอย่างที่เราเห็นนั่นคือค่าที่มากที่สุดที่เป็นไปได้ที่สามารถแสดงด้วย 8 บิต

ในเครื่องของฉันและ int และ long นั้นเหมือนกันแต่ละอันสามารถถือได้ระหว่าง -2 31ถึง 2 31 - 1 จากประสบการณ์ของฉันขนาดที่พบมากที่สุดในเครื่องเดสก์ท็อป 32 บิตที่ทันสมัย


ขนาดต่ำสุดสำหรับประเภทจำนวนเต็มกำหนดโดยมาตรฐานที่เกี่ยวข้อง (แม้ว่าจะไม่มีขนาดที่แน่นอนก็ตาม)
คาเฟ่

13

หากต้องการทราบข้อ จำกัด ในระบบของคุณ :

#include <iostream>
#include <limits>
int main(int, char **) {
  std::cout
    << static_cast< int >(std::numeric_limits< char >::max()) << "\n"
    << static_cast< int >(std::numeric_limits< unsigned char >::max()) << "\n"
    << std::numeric_limits< short >::max() << "\n"
    << std::numeric_limits< unsigned short >::max() << "\n"
    << std::numeric_limits< int >::max() << "\n"
    << std::numeric_limits< unsigned int >::max() << "\n"
    << std::numeric_limits< long >::max() << "\n"
    << std::numeric_limits< unsigned long >::max() << "\n"
    << std::numeric_limits< long long >::max() << "\n"
    << std::numeric_limits< unsigned long long >::max() << "\n";
}

โปรดทราบว่าlong longถูกต้องตามกฎหมายใน C99 และใน C ++ 11 เท่านั้น


9

คนอื่น ๆ ที่นี่จะโพสต์ลิงก์ไปยัง data_sizes และ precisions เป็นต้น
ฉันจะบอกคุณว่าจะคิดออกได้อย่างไร
เขียนแอพเล็ก ๆ ที่จะทำสิ่งต่อไปนี้

unsigned int ui;
std::cout <<  sizeof(ui));

สิ่งนี้จะ (ขึ้นอยู่กับคอมไพเลอร์และไฟล์เก็บถาวร) พิมพ์ 2, 4 หรือ 8, บอกว่ายาว 2 ไบต์, ยาว 4 ไบต์เป็นต้น

สมมติว่าเป็น 4

ตอนนี้คุณต้องการเก็บค่าสูงสุด 4 ไบต์ได้ค่าสูงสุดสำหรับหนึ่งไบต์คือ (ในเลขฐานสิบหก) 0xFF ค่าสูงสุดของสี่ไบต์คือ 0x ตามด้วย 8 f (หนึ่งคู่ของ f สำหรับแต่ละไบต์ 0x จะบอกคอมไพเลอร์ว่าสตริงต่อไปนี้เป็นเลขฐานสิบหก) ตอนนี้เปลี่ยนโปรแกรมของคุณเพื่อกำหนดค่านั้นและพิมพ์ผลลัพธ์

unsigned int ui = 0xFFFFFFFF;
std::cout <<  ui;

นั่นคือค่าสูงสุดที่ int ที่ไม่ได้ลงนามสามารถถือได้ซึ่งแสดงในการแทนค่าฐาน 10

ตอนนี้ทำสิ่งนั้นเพื่อความยาวกางเกงขาสั้นและค่า INTEGER อื่น ๆ ที่คุณอยากรู้

หมายเหตุ: วิธีนี้จะใช้ไม่ได้กับตัวเลขทศนิยม (เช่นคู่หรือลอย)

หวังว่านี่จะช่วยได้


1
หากคุณลองใช้ด้วย ints ที่มีการลงนามคุณจะได้ตัวเลขติดลบ อ่าน "คำชมเชยของสองคน" (ลิงก์ที่ให้มา) มันง่ายมากที่จะหาข้อมูลทั้งหมด (บวกและลบ) สำหรับสิ่งเหล่านี้ en.wikipedia.org/wiki/Twos_Compliment
Binary Worrier

7

ใน C ++ ตอนนี้ int และข้อมูลอื่น ๆ จะถูกจัดเก็บโดยใช้วิธีการชมเชย 2 นั่นหมายความว่าช่วงคือ:

-2147483648 to 2147483647

หรือ -2 ^ 31 ถึง 2 ^ 31-1

1 บิตถูกสงวนไว้สำหรับ 0 ดังนั้นค่าบวกจึงน้อยกว่า 2 ^ (31)


4

คุณสามารถใช้ฟังก์ชันnumeric_limits<data_type>::min()and ที่numeric_limits<data_type>::max()มีอยู่ในlimitsไฟล์ส่วนหัวและค้นหาขีด จำกัด ของข้อมูลแต่ละประเภทได้

#include <iostream>
#include <limits>
using namespace std;
int main()
{
    cout<<"Limits of Data types:\n";    
    cout<<"char\t\t\t: "<<static_cast<int>(numeric_limits<char>::min())<<" to "<<static_cast<int>(numeric_limits<char>::max())<<endl;
    cout<<"unsigned char\t\t: "<<static_cast<int>(numeric_limits<unsigned char>::min())<<" to "<<static_cast<int>(numeric_limits<unsigned char>::max())<<endl;
    cout<<"short\t\t\t: "<<numeric_limits<short>::min()<<" to "<<numeric_limits<short>::max()<<endl;
    cout<<"unsigned short\t\t: "<<numeric_limits<unsigned short>::min()<<" to "<<numeric_limits<unsigned short>::max()<<endl;
    cout<<"int\t\t\t: "<<numeric_limits<int>::min()<<" to "<<numeric_limits<int>::max()<<endl;
    cout<<"unsigned int\t\t: "<<numeric_limits<unsigned int>::min()<<" to "<<numeric_limits<unsigned int>::max()<<endl;
    cout<<"long\t\t\t: "<<numeric_limits<long>::min()<<" to "<<numeric_limits<long>::max()<<endl;
    cout<<"unsigned long\t\t: "<<numeric_limits<unsigned long>::min()<<" to "<<numeric_limits<unsigned long>::max()<<endl;
    cout<<"long long\t\t: "<<numeric_limits<long long>::min()<<" to "<<numeric_limits<long long>::max()<<endl;
    cout<<"unsiged long long\t: "<<numeric_limits<unsigned long long>::min()<<" to "<<numeric_limits<unsigned long long>::max()<<endl;
    cout<<"float\t\t\t: "<<numeric_limits<float>::min()<<" to "<<numeric_limits<float>::max()<<endl;
    cout<<"double\t\t\t: "<<numeric_limits<double>::min()<<" to "<<numeric_limits<double>::max()<<endl;
    cout<<"long double\t\t: "<<numeric_limits<long double>::min()<<" to "<<numeric_limits<long double>::max()<<endl;
}

ผลลัพธ์จะเป็น: ขีด จำกัด ของชนิดข้อมูล:

  • ถ่าน: -128 ถึง 127
  • ถ่านที่ไม่ได้ลงชื่อ: 0 ถึง 255
  • สั้น: -32768 ถึง 32767
  • สั้นที่ไม่ได้ลงนาม: 0 ถึง 65535
  • int: -2147483648 ถึง 2147483647
  • int ที่ไม่ได้ลงนาม: 0 ถึง 4294967295
  • ยาว: -2147483648 ถึง 2147483647
  • ไม่ได้ลงชื่อยาว: 0 ถึง 4294967295
  • ยาว: -9223372036854775808 ถึง 9223372036854775807
  • ไม่ได้ลงนาม long long: 0 ถึง 18446744073709551615
  • ลอย: 1.17549e-038 ถึง 3.40282e + 038
  • สองเท่า: 2.22507e-308 ถึง 1.79769e + 308
  • คู่ยาว: 3.3621e-4932 ถึง 1.18973e + 4932

2

สำหรับประเภทข้อมูลที่ไม่ได้ลงชื่อจะไม่มีบิตเครื่องหมายและบิตทั้งหมดเป็นข้อมูล ในขณะที่ประเภทข้อมูลที่ลงนาม MSB จะระบุบิตลงชื่อและบิตที่เหลือเป็นข้อมูล

ในการค้นหาช่วงให้ทำสิ่งต่อไปนี้:

ขั้นตอน: 1 -> ค้นหาจำนวนไบต์สำหรับชนิดข้อมูลให้

ขั้นตอน: 2 -> ใช้การคำนวณต่อไปนี้

      Let n = no of bits in data type  

      For signed data type ::
            Lower Range = -(2^(n-1)) 
            Upper Range = (2^(n-1)) - 1)  

      For unsigned data type ::
            Lower Range = 0 
            Upper Range = (2^(n)) - 1 

สำหรับเช่น

สำหรับขนาด int ที่ไม่ได้ลงชื่อ = 4 ไบต์ (32 บิต) -> ช่วง [0, (2 ^ (32)) - 1]

สำหรับขนาด int ที่ลงชื่อ = 4 ไบต์ (32 บิต) -> ช่วง [- (2 ^ (32-1)), (2 ^ (32-1)) - 1]


1

ไม่ได้เฉพาะบางส่วนของตัวเลขสิบหลักเท่านั้นที่สามารถเก็บไว้ใน int long ที่ไม่ได้ลงนามซึ่งมีช่วงที่ถูกต้องคือ 0 ถึง 4,294,967,295 คุณสามารถอ้างถึงสิ่งนี้: http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx



0

int ยาวที่ไม่ได้ลงนามสามารถถือตัวเลขสิบหลัก (1,000,000,000 - 9,999,999,999) บนคอมพิวเตอร์ 32 บิตได้

ไม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.