số nguyên lớn nhất có thể được lưu trữ trong một đôi


Câu trả lời:


506

Số nguyên lớn nhất / lớn nhất có thể được lưu trữ trong một gấp đôi mà không làm mất độ chính xác giống như giá trị lớn nhất có thể có của một gấp đôi. Đó là, DBL_MAXhoặc xấp xỉ 1,8 × 10 308 (nếu gấp đôi của bạn là gấp đôi 64-bit 64 bit). Đó là một số nguyên. Nó được đại diện chính xác. Nhiều hơn những gì bạn muốn?

Tiếp tục, hỏi tôi số nguyên lớn nhất là gì, sao cho nó và tất cả các số nguyên nhỏ hơn có thể được lưu trữ trong nhân đôi 64 bit mà không làm mất độ chính xác. Bộ đôi IEEE 64 bit có 52 bit mantissa, vì vậy tôi nghĩ đó là 2 53 :

  • Không thể lưu trữ 2 53 + 1, vì 1 ở đầu và 1 ở cuối có quá nhiều số không ở giữa.
  • Bất cứ thứ gì nhỏ hơn 2 53 đều có thể được lưu trữ, với 52 bit được lưu trữ rõ ràng trong lớp phủ, và sau đó số mũ có hiệu lực mang lại cho bạn một số khác.
  • 2 53 rõ ràng có thể được lưu trữ, vì đó là một sức mạnh nhỏ của 2.

Hoặc một cách khác để xem xét nó: một khi độ lệch đã được loại bỏ theo số mũ và bỏ qua bit dấu là không liên quan đến câu hỏi, giá trị được lưu trữ bởi một nhân đôi là lũy thừa 2, cộng với số nguyên 52 bit nhân với 2 số mũ - 52 . Vì vậy, với số mũ 52, bạn có thể lưu trữ tất cả các giá trị từ 2 52 đến 2 53  - 1. Sau đó, với số mũ 53, số tiếp theo bạn có thể lưu trữ sau 2 53 là 2 53 + 1 × 2 53 - 52 . Vì vậy, mất độ chính xác đầu tiên xảy ra với 2 53 + 1.


126
+1 Công việc tốt nhận thấy rằng câu hỏi không thực sự có nghĩa là những gì người hỏi có thể dự định và cung cấp cả hai câu trả lời ("đúng về mặt kỹ thuật" và "có thể được mong đợi").
Pascal Cuoq

62
Hoặc "gây rối" và "cố gắng giúp đỡ" khi tôi có xu hướng gọi họ :-)
Steve Jessop

8
Tôi cúi chào Tony the Pony, và không ai khác.
Steve Jessop

11
Bạn không có nghĩa là "tất cả các số nguyên nhỏ hơn", bạn có nghĩa là tất cả các số nguyên có độ lớn bằng hoặc nhỏ hơn. Bởi vì có rất nhiều số nguyên âm dưới 2 ^ 53 và không thể được biểu diễn chính xác trong một đôi.
Khách sạn miền Nam

13
Tôi có nghĩa là nhỏ hơn, và đó chính xác là những gì tôi muốn nói khi tôi nói nhỏ hơn :-) -1.000.000 nhỏ hơn 1, nhưng nó không nhỏ hơn.
Steve Jessop

77

9007199254740992 (đó là 9,007,199,254,740,992) không có bảo đảm :)

Chương trình

#include <math.h>
#include <stdio.h>

int main(void) {
  double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
  while (dbl + 1 != dbl) dbl++;
  printf("%.0f\n", dbl - 1);
  printf("%.0f\n", dbl);
  printf("%.0f\n", dbl + 1);
  return 0;
}

Kết quả

9007199254740991
9007199254740992
9007199254740992

7
Giả sử nó sẽ 'đóng' nhưng nhỏ hơn 2 ^ N, thì thử nghiệm nhanh hơn double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);sẽ cho kết quả tương tự
Seph

4
@Seph cái gì ...? Không? while (dbl == --dbl)sẽ lặp đi lặp lại mãi mãi hay không. :) (trong trường hợp này, hoàn toàn không, vì nó là 2 ^ N). Bạn sẽ phải tiếp cận nó từ bên dưới. Nó thực sự cũng sẽ dẫn đến một ít hơn kết quả mong đợi (vì một kiểm tra trong vòng lặp while giảm dbl). Và nó phụ thuộc vào thứ tự thực hiện, nếu việc giảm được thực hiện trước hoặc sau khi đánh giá phía bên trái (không được xác định theo như tôi biết). Nếu đó là trước đây, nó sẽ luôn luôn đúng và lặp lại mãi mãi.
falstro

10
Có thể chỉ ra rằng 2 ^ 53 = 9,007,199,254,740,992 ở đâu đó.
Xonatron

1
Thật khó để tranh luận với điều này! Thử nghiệm thú vị
MattM

Một điểm yếu để sử dụng while (dbl + 1 != dbl) dbl++;trong đó dbl + 1 != dblcó thể đánh giá bằng cách sử dụng long doubletoán học - xem xét FLT_EVAL_METHOD == 2. Điều này có thể kết thúc trong một vòng lặp vô hạn.
chux - Phục hồi Monica

25

Wikipedia có điều này để nói trong cùng bối cảnh với một liên kết đến IEEE 754 :

Trên một hệ thống máy tính thông thường, số dấu phẩy động nhị phân 'chính xác kép' (64 bit) có hệ số 53 bit (một trong số đó được ngụ ý), số mũ 11 bit và một bit dấu.

2 ^ 53 chỉ hơn 9 * 10 ^ 15.


@Steve Jessop ít nhiều, đó thực sự là những gì tôi đang nói. Tôi cũng đã gặp phải các hệ thống phần cứng không có FPU vẫn cần phải tuân thủ theo chuẩn IEEE, vì vậy những thứ "hệ thống điển hình" không thực sự giúp tôi nếu tôi quay lại đây 8 tháng sau và cần thông tin tương tự cho bộ vi điều khiển dựa trên 68K của tôi (giả sử nó không có FPU ... tôi không thể nhớ).
San Jacinto

14
@San Jacinto - "Điều này là vô ích" là quá khắc nghiệt. Câu trả lời là khá hữu ích, chỉ là không hữu ích như nó sẽ có nếu nó bao gồm nhận xét rằng các hệ thống máy tính thông thường thực sự sử dụng sự phục hồi của IEEE 754.
Stephen C. Steel

@Stephen C. Steel, thực ra bạn đúng. Theo kịch bản của tôi, quay trở lại vấn đề này sau đó và tìm kiếm tối đa của IEEE, điều này không rõ ràng về "hệ thống điển hình" là gì, nhưng vẫn có công trong câu trả lời bên cạnh khiếu nại này.
San Jacinto

20

Số nguyên lớn nhất có thể được biểu diễn trong IEEE 754 double (64 bit) giống như giá trị lớn nhất mà loại có thể biểu thị, vì giá trị đó tự nó là một số nguyên.

Điều này được thể hiện dưới dạng 0x7FEFFFFFFFFFFFFF, được tạo thành từ:

  • Dấu bit 0 (dương) thay vì 1 (âm)
  • Số mũ tối đa 0x7FE(2046 đại diện cho 1023 sau khi độ lệch được trừ) thay vì 0x7FF(2047 chỉ ra a NaNhoặc vô cùng).
  • Lớp phủ tối đa 0xFFFFFFFFFFFFFlà 52 bit tất cả 1.

Trong hệ nhị phân, giá trị là 1 ẩn theo sau là 52 số khác từ mantissa, sau đó là 971 số không (1023 - 52 = 971) từ số mũ.

Giá trị thập phân chính xác là:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

Đây là khoảng 1,8 x 10 308 .


Điều gì về giá trị lớn nhất mà nó có thể đại diện cho tất cả các giá trị giữa nó và không thể biểu diễn liên tục?
Aaron Franke

@AaronFranke Câu hỏi không hỏi về đại diện tiếp giáp, nhưng câu trả lời cho câu hỏi khác nhau đó đã được đưa vào hầu hết các câu trả lời khác ở đây, hoặc thậm chí sai khi trả lời thực tế. Đó là 2⁵³ (2 với sức mạnh của 53).
Simon Biber

8

Bạn cần nhìn vào kích thước của lớp phủ. Số điểm động 64 bit 64 bit (có 52 bit, cộng 1 ngụ ý) có thể biểu diễn chính xác các số nguyên có giá trị tuyệt đối nhỏ hơn hoặc bằng 2 ^ 53.


8
Nó chính xác có thể đại diện cho 2 ^ 53, quá :-)
Steve Jessop

6

2
câu trả lời này sẽ tốt hơn nhiều với một trích dẫn.
San Jacinto

2
@Carl tốt, nếu số nguyên có các số 0 nằm bên trái, thì nó được lưu trữ chính xác.
Wilhelm

4
@all bạn downvoters: 1.7976931348623157 × 10 ^ 308 một số nguyên chính xác. Bạn có cần phải tham dự các lớp học toán sửa chữa hay gì không ??
Dan Mould

6
Chúng ta đang đi xuống ngữ nghĩa ở đây trong cuộc thảo luận về câu trả lời vô vọng này. Đúng, con số đó có thể được trình bày chính xác và do đó đáp ứng thư của câu hỏi. Nhưng tất cả chúng ta đều biết đó là một hòn đảo nhỏ chính xác trong một đại dương gần, và hầu hết chúng ta đã nội suy chính xác câu hỏi có nghĩa là "con số lớn nhất vượt ra ngoài độ chính xác." Ah, thật tuyệt vời khi CompSci là một môn khoa học chính xác phải không? :)
Carl Smotricz

2
@DanMoulding 1.7976931348623157 × 10 ^ 308 là một số nguyên chính xác, nhưng tôi khá chắc chắn rằng số nguyên cụ thể này không thể được lưu trữ chính xác trong một đôi.
Pascal Cuoq

2

DECIMAL_DIGtừ <float.h>nên đưa ra ít nhất một xấp xỉ hợp lý của điều đó. Vì liên quan đến các chữ số thập phân và nó thực sự được lưu trữ dưới dạng nhị phân, bạn có thể có thể lưu trữ một cái gì đó lớn hơn một chút mà không mất độ chính xác, nhưng chính xác thì khó nói bao nhiêu. Tôi cho rằng bạn sẽ có thể tìm ra nó từ FLT_RADIXDBL_MANT_DIG, nhưng tôi không chắc là tôi hoàn toàn tin tưởng vào kết quả.


Điều này không cung cấp một câu trả lời cho câu hỏi. Để phê bình hoặc yêu cầu làm rõ từ một tác giả, hãy để lại nhận xét bên dưới bài đăng của họ.
MichaelChirico

@MichaelChirico: Điều này trả lời câu hỏi anh ta định hỏi, vì nó tồn tại khi câu trả lời được viết. Để xem lịch sử chỉnh sửa của câu hỏi, nhấp vào liên kết "đã chỉnh sửa ngày 19 tháng 6 năm 14 lúc 11:40" ở cuối câu hỏi.
Jerry Coffin

câu trả lời của bạn đọc giống như một bình luận bởi vì nó dường như thiếu sự tự tin / ủy quyền mà một câu trả lời nên có ("nên đưa ra ít nhất là hợp lý ..." "chính xác là bao nhiêu ... thật khó để nói" "Tôi cho rằng ... "). Tôi không có chuyên môn về câu hỏi hoặc câu trả lời, vì vậy tôi có thể sai; chỉ cần đưa hai xu của tôi vào là tôi đã được gửi đến đây từ hàng đánh giá (mà tôi đoán có nghĩa là những người dùng khác đã gắn cờ câu trả lời của bạn).
MichaelChirico

1
@MichaelChirico: Họ có thể có - bạn ở xa người duy nhất không biết gì về vấn đề này; Điều khiến bạn khác thường là bạn nhận ra mình không biết gì về nó. Hầu hết các câu trả lời có vẻ có thẩm quyền về độ chính xác của số dấu phẩy động trong C chỉ đơn giản là nhầm lẫn. Ví dụ, nhiều (hầu hết) trong số chúng ở trên dựa trên giả định sai rằng doubletương ứng trực tiếp với một loại cụ thể của IEEE, nhưng điều đó không bắt buộc và khi câu trả lời này được viết, câu hỏi cũng không đề cập đến một loại cụ thể nào.
Jerry Coffin

hiểu rồi. Có lẽ tôi muốn đề nghị thêm thông tin đó vào câu trả lời.
MichaelChirico
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.