2009-09-13 99 views

Trả lời

0

Trong trình biên dịch Borland và Microsoft, __int64 có lẽ là lớn nhất bạn có thể nhận được.

9

Loại dữ liệu long long là kiểu dữ liệu tích hợp tích hợp lớn nhất trong tiêu chuẩn C99 và C++ 0x. Cũng như với tất cả các kiểu dữ liệu tích phân khác, long long không được cung cấp một kích thước chính xác theo byte. Thay vào đó, nó được xác định là ít nhất một số nguyên 64 bit. Trong khi long long không phải là một phần của tiêu chuẩn C++ chính thức, nó được hỗ trợ khắp mọi nơi trên các trình biên dịch hiện đại. Tuy nhiên, lưu ý rằng nhiều trình biên dịch cho các máy tính để bàn hiện đại xác định longlong long là chính xác 64 bit, trong khi nhiều trình biên dịch cho các bộ xử lý nhúng xác định long như 32 bit và long long như 64 bit (rõ ràng là ít ngoại lệ).

Nếu bạn cần độ chính xác cao hơn hoặc hoàn toàn không thể sử dụng tiện ích mở rộng ngôn ngữ long long, bạn sẽ phải sử dụng một trong các thư viện C hoặc C++ được thiết kế để hoạt động với số lượng cực lớn hoặc nhỏ.

+3

"... miễn là dài và dài cả hai sẽ là 64 bit trên hầu hết các CPU máy tính để bàn hiện đại". Không đúng. Phụ thuộc vào trình biên dịch. Trong mô hình LLP64 (được sử dụng bởi VC), 'long' vẫn là 32-bit và' long long' là 64 bit. –

+1

Xem liên kết này http://en.wikipedia.org/wiki/LLP64#Specific_data_models cho các mô hình bộ nhớ 64 bit có thể. –

+10

FYI, 'long long' không nằm trong tiêu chuẩn C++. Nó được thêm vào C trong C99. Hiện tại, nó là một phần mở rộng phổ biến được hỗ trợ bởi hầu hết các trình biên dịch. –

2

Bạn có thể dễ dàng nhận được kiểu dữ liệu lớn hơn bằng cách xác định Lớp của riêng bạn. Bạn có thể lấy cảm hứng từ lớp học BigInteger bằng Java. Đó là một trong những tốt đẹp, nhưng nó không nhất thiết phải là một số nguyên thực tế ngay cả khi nó hoạt động chính xác như một.

4

Có 128 bit số nguyên đóng gói và định dạng dấu chấm động được xác định trong xmmintrin.h trên trình biên dịch hỗ trợ SSE để cho phép sử dụng thanh ghi SSE và hướng dẫn. Chúng không phải là một phần của tiêu chuẩn C++, nhưng vì chúng được hỗ trợ bởi MSVC, GCC và Trình biên dịch Intel C++ có một mức hỗ trợ đa nền tảng (ít nhất là OS X, Linux và Windows cho CPU Intel). Các ISA khác có các phần mở rộng SIMD do đó có lẽ các phần mở rộng cụ thể của nền tảng/trình biên dịch khác hỗ trợ các hướng dẫn SIMD 128 hoặc 256 bit. Tập lệnh AVX sắp tới của Intel sẽ có các thanh ghi 256 bit, vì vậy chúng ta sẽ thấy một tập hợp các kiểu dữ liệu và nội tại mới cho điều đó.

Chúng không hoạt động giống như các kiểu dữ liệu tích hợp (tức là bạn phải sử dụng các hàm bên trong thay vì toán tử để thao tác chúng, và chúng hoạt động với các hoạt động SIMD). đăng ký trên phần cứng mà họ xứng đáng đề cập đến.

Details about Streaming SIMD Extension (SSE)Intrinsics

21

Lớn nhất nguyên kiểu chuẩn C++ là long.

C có long long và C++ 0x cũng sẽ thêm phần đó và dĩ nhiên bạn có thể triển khai loại số nguyên tùy chỉnh của riêng mình, có lẽ thậm chí là lớp BigInt.

Nhưng về mặt kỹ thuật, hãy xem xét các loại số nguyên được tích hợp sẵn, long là câu trả lời của bạn.

+1

Về mặt kỹ thuật, chuẩn C++ tiếp theo có thể không có kiểu dài. Không có gì không thể rút khỏi tiêu chuẩn ngay cả ở giai đoạn cuối này. Nhưng 1 để trở thành người đi bộ (đúng) :-) – paxdiablo

+3

và bạn gọi * tôi * một người đi bộ. ;) Nhưng vâng, điểm công bằng. Tại thời điểm này, có vẻ như nó sẽ được đưa vào C++ 0x, nhưng ai biết được. :) – jalf

+8

Bây giờ chúng ta biết — 'long long' là trong C++ 11. –

7

Bạn có thể muốn tránh lo lắng về các tên nguyên thủy bằng cách ánh xạ tới loại lớn nhất (được nhận biết đầy đủ) trên kiến ​​trúc biên dịch qua <cstdint> và typedefs intmax_tuintmax_t.

Tôi đã rất ngạc nhiên khi không ai khác nói điều này, nhưng nghiên cứu cursory cho thấy nó đã được thêm vào trong C++ 11, có thể giải thích được việc thiếu các đề cập trước đó. (Mặc dù kiểu nguyên thủy mới/tích hợp sẵn của nó long long được trích dẫn!)

Một số trình biên dịch cũng có thể cung cấp các loại lớn hơn, mặc dù chúng có thể đi kèm với hãy cẩn thận, ví dụ: Why in g++ std::intmax_t is not a __int128_t?

Cá nhân, tôi đang sử dụng cstdint vì nó dễ dàng hơn để nhanh chóng xem có bao nhiêu byte tối thiểu tôi sử dụng - thay vì phải nhớ số lượng bit mà một nguyên thủy đã cho tương ứng với - và chuẩn có nghĩa là nó tránh được các kiểu của tôi phụ thuộc vào nền tảng. Ngoài ra, đối với những gì tôi làm, uint8_t nhanh hơn và nhanh hơn vô tận unsigned char s!

chỉnh sửa: Trong hindsight, tôi muốn làm rõ: uint8_t không được đảm bảo tương đương với unsigned char. Chắc chắn, đó là trên máy của tôi, và nó có thể là dành cho bạn, quá. Nhưng sự tương đương này không được yêu cầu bởi tiêu chuẩn; xem: When is uint8_t ≠ unsigned char? Vì lý do đó, bây giờ khi tôi cần khả năng đặc biệt được xác định tiêu chuẩn của [[un]signed] char, tôi chỉ sử dụng điều đó.

+0

downvoter: Có một vấn đề thực sự mà bạn có thể nói cho phần còn lại của chúng tôi về, hoặc là bạn chỉ cảm thấy cay đắng về một cái gì đó không liên quan? –

3

boost::multiprecision::cpp_int là loại số nguyên chính xác tùy ý. Vì vậy, không có "datatype số nguyên lớn nhất" trong C + +. Chỉ cần một loại nội dung tích hợp lớn nhất, AFAIK là long trong tiêu chuẩn C++.

0

Các loại dữ liệu __int128_t và __uint128_t (unsigned __int128_t) là 128 bit dài, gấp đôi kích thước của một dài (dài 64 bit cho những người mới đến C++). Tuy nhiên, nếu bạn định sử dụng chúng, thì bạn cần thực hiện một số quá tải vì kiểu dữ liệu int128 không được hỗ trợ quá sâu (ít nhất là trong Mingw). Đây là một ví dụ về cách bạn có thể sử dụng nó để hiển thị 2^x-1 cho đến 2^128-1

#include <iostream> 

char base10_lookup_table[10]={'0','1','2','3','4','5','6','7','8','9'}; 

std::ostream& 
operator<<(std::ostream& dest, __int128 value) 
{ 
    std::ostream::sentry s(dest); 
    if (s) { 
     __uint128_t tmp = value < 0 ? -value : value; 
     char buffer[ 128 ]; 
     char* d = std::end(buffer); 
     do 
     { 
      -- d; 
      *d = base10_lookup_table[ tmp % 10 ]; 
      tmp /= 10; 
     } while (tmp != 0); 
     if (value < 0) { 
      -- d; 
      *d = '-'; 
     } 
     int len = std::end(buffer) - d; 
     if (dest.rdbuf()->sputn(d, len) != len) { 
      dest.setstate(std::ios_base::badbit); 
     } 
    } 
    return dest; 
} 

std::ostream& 
operator<<(std::ostream& dest, unsigned __int128 value) 
{ 
    std::ostream::sentry s(dest); 
    if (s) { 
     __uint128_t tmp = value < 0 ? -value : value; 
     char buffer[ 128 ]; 
     char* d = std::end(buffer); 
     do 
     { 
      -- d; 
      *d = base10_lookup_table[ tmp % 10 ]; 
      tmp /= 10; 
     } while (tmp != 0); 
     if (value < 0) { 
      -- d; 
      *d = '-'; 
     } 
     int len = std::end(buffer) - d; 
     if (dest.rdbuf()->sputn(d, len) != len) { 
      dest.setstate(std::ios_base::badbit); 
     } 
    } 
    return dest; 
} 



int main (void) 
{ 
    __uint128_t big_value = 0;  //unsigned int128 

    for (unsigned char i=0; i!=129; ++i) //I am using an unsigned char because it can hold all the values that will be used 
    { 
     std::cout << "1 less than 2 to the power of " << int(i) << " = \0" << big_value << "\n"; 
     big_value |= (__uint128_t)1 << i; 
    } 

    return 0; //formal way of exiting 
} 

Vấn đề với datatype int128 là không phải tất cả các trình biên dịch có thể hỗ trợ nó.

Các vấn đề liên quan