2009-09-21 29 views
89

Một số ngôn ngữ lập trình phổ biến sử dụng đánh số tháng bị tắt bởi 1 - JavaScript xuất hiện, cũng như Java và nếu bộ nhớ phân phát, C là một ngôn ngữ khác. Tôi có một số câu hỏi sau:Số tháng dựa trên số không

  • Nếu bạn đang đi để được bỏ qua việc đánh số tháng sử dụng bởi giáo dân, thì tại sao không vì lợi ích của tính nhất quán cũng bỏ qua ngày đánh số được sử dụng bởi giáo dân, và số ngày trong mỗi tháng bắt đầu từ 0?
  • Tại sao quá phổ biến này?
  • Ý tưởng của ai là điều này ngay từ đầu?
+0

Mảng, bắt đầu bằng 0 và mọi người đề cập đến ngày theo số? – glasnt

+10

@TomatoSandwich: khá thường xuyên mọi người tham khảo _months_ theo số và họ đánh số chúng bắt đầu từ _1_. –

+2

Các lập trình viên API không phải là vị thần bằng cách này; đôi khi những sai lầm xâm nhập vào việc triển khai; chỉ cần đối phó với nó. Không phải là đây chính xác là một trường hợp (bạn thậm chí không nói ngôn ngữ nào), nhưng không mong đợi mọi thứ trở nên hoàn hảo. Tôi ngưỡng mộ muốn biết lý do. –

Trả lời

48

Việc sử dụng số không để bắt đầu đếm thực sự là một mẹo tối ưu hóa từ các lập trình viên lắp ráp. Thay vì chỉ định 1 cho thanh ghi số, họ XOR'ed đăng ký với chính nó, đó là hơi nhanh hơn trong chu kỳ CPU. Điều này có nghĩa là việc đếm sẽ bắt đầu bằng 0 và sẽ luôn phụ thuộc vào độ dài của các phần tử, trừ phần tử cuối cùng.

Ngoài ra, việc sử dụng số không cũng phổ biến với con trỏ arithmetics nơi bạn sẽ sử dụng một con trỏ cơ sở trỏ vào một số bộ nhớ được phân bổ, cộng với một con trỏ thứ hai mà sẽ được tại một bù đắp từ con trỏ cơ sở này. Ở đây, việc sử dụng giá trị 0 tạo ra rất nhiều ý nghĩa để trỏ bù đắp cho phần cơ sở của khối bộ nhớ. (Logic mảng chung có xu hướng là địa chỉ cơ sở cộng với kích thước bản ghi bù x.)

Và số tháng không dựa trên số không? Thông thường, nhiều môi trường lập trình tính toán dữ liệu như một số ngày kể từ khi một số dữ liệu mặc định. Ngày 31 tháng 12 năm 1899 là một ngày phổ biến, mặc dù đã có rất nhiều ngày khác được sử dụng làm ngày cơ sở. Tất cả các ngày khác được bù đắp từ cơ sở này và sẽ chỉ được lưu trữ dưới dạng một số duy nhất. Phân số sẽ được sử dụng để chỉ giờ, phút và giây, trong đó 0,25 sẽ là 24/4 = 6 giờ. Do đó, để biến đổi một ngày thành một ngày thực, tất cả môi trường phải làm là chuyển đổi số này thành một ngày thực.

Tuy nhiên, sự kết hợp của mảng dựa trên không và giá trị tháng dựa trên 1 sẽ gây ra sự cố. Để lấy tên tháng của tháng 9, bạn sẽ phải lấy mục 8 từ mảng tháng. Một số nhà phát triển sẽ hài lòng với việc giảm số tháng trước khi nhận được tên của nó. Những người khác thích thay đổi tháng thành một cái gì đó không dựa trên kể từ khi mọi người chỉ muốn biết tên, không phải là số. Đó là một cái nhìn cá nhân.

+79

Các nhà xây dựng JavaScript và AS3 Date nhận giá trị thực cho mọi thứ "ngoại trừ" tháng, vì lý do không xác định phải được chỉ định là không dựa trên 0 . Đó chắc chắn là một thiết kế API khủng khiếp. – Triynko

+3

Tôi đồng ý. Điều này chỉ tốn một giờ để cố gắng tìm ra lý do tại sao ngày của tôi là một tháng. Nó không thực sự có ý nghĩa cho tất cả mọi thứ được 1 dựa trừ tháng. Thật không may, nó có thể unfixable, nếu không chúng tôi sẽ kết thúc với một vấn đề Y2K :-). –

+1

Tl; dr: Vì tra cứu mảng 'monthName [monthNumber]' hoặc 'mon_name [tm_mon]' với ký hiệu [time.h] (http://www.cplusplus.com/reference/ctime/asctime/). – Perseids

4

Đó là những gì nó là, và trọng lượng rất lớn của phần mềm được xây dựng để giả định đó có nghĩa là nó sẽ được khoảng một thời gian.

Ý kiến ​​của tôi là do lỗi của C và tất cả các ngôn ngữ khác của Johnie-gần đây chỉ phù hợp với ngôn ngữ đó.

Bạn nhận được một số tình huống thú vị từ những người không biết rõ hơn. Một trong số ít lỗi của Y2K mà nhóm của chúng tôi tìm thấy là một trang web tự hào tuyên bố năm 19100 đơn giản chỉ vì họ đã bắt đầu từ năm struct tm với chữ "19".

+0

Ít nhất một người (không phải tôi) đã xác định các hàm "getRealMonth" và "setRealMonth" để sử dụng trong các tập lệnh của mình. Tôi không đổ lỗi cho anh ta một chút. –

+1

Đặc biệt dành cho tham khảo lỗi Y2K. –

4

Có, người La Mã cũng gặp vấn đề với số không.

Đây là chỉ một [phi trực quan] hậu quả của toán học (là một thành phần mạnh mẽ của chương trình, đặc biệt là chương trình đầu) xác định bằng không là người đầu tiên (có vấn đề hạn mà một) sản, dương * Số tự nhiên, và vì một mảng được lập chỉ mục với số thực, số tự nhiên, phần tử "đầu tiên" có tại chỉ số 0.

Tháng thực sự được đặt tên trong một mảng, trong đó ngày và năm là giá trị được đánh số - có lẽ sẽ hữu ích hơn khi nghĩ của ngày/năm như trong mảng trông giống như {"1", "2", "3", ...}.

Như tại sao điều này là rất phổ biến (ngoài việc bị về mặt toán học chính xác) cũng tất cả các ngôn ngữ bạn liệt kê xuống từ một nguồn gốc chung cho một điều ...

Edit:

Nhìn sâu hơn vào nó, chi tiết liên kết này wikipedia một số lý do tốt và thú vị để lập chỉ mục 0 (không trực tiếp nói đến lý do tại sao tháng không được lập chỉ mục nhưng tôi nghĩ điều đó đã được đề cập) và liên kết SO này đã trả lời câu hỏi trước đó.

Có vẻ như ý kiến ​​hiện tại là "tai nạn lịch sử" hoặc "vì tháng không phải là số nên không thể so sánh với bộ nhớ ngày/năm" tùy thuộc vào người bạn yêu cầu.

* Xin lỗi, xin lỗi, vật lý! = Toán học quay lại cắn tôi ở đó. Giờ hãy để tay tôi ra.

+5

Zero không phải là số dương. Nó cũng không phải là số âm. –

+0

Điểm tốt, có lẽ bạn nên thay đổi nó thành "số tự nhiên". – paxdiablo

+1

Thú vị, tôi luôn nghĩ rằng các mảng C bắt đầu bằng 0 để đơn giản hóa số học con trỏ: 'a [0]' == '* (a + 0)'. –

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