2012-04-08 28 views
6

Được nhìn qua câu trả lời khác và tôi vẫn không hiểu được modulo cho số âm trong pythonModulo cho cổ tức tiêu cực trong Python

Ví dụ câu trả lời bằng cách df

x == (x/y)*y + (x%y) 

nên nó có ý nghĩa rằng (-2)% 5 = -2 - (-2/5) * 5 = 3

Điều này không (-2 - (-2/5) * 5) = 0 hoặc tôi có điên không? Modulus operation with negatives values - weird thing?

Cùng với điều này negative numbers modulo in python đâu ông đã nhận được -2 từ đâu?

Cuối cùng, nếu dấu hiệu phụ thuộc vào cổ tức tại sao cổ tức không tiêu cực có cùng sản lượng như đối tác tích cực của họ?

Ví dụ đầu ra của

print([8%5,-8%5,4%5,-4%5]) 

[3, 2, 4, 1] 
+0

Bạn có thể sử dụng 'math.fmod' để có được hành vi tương tự như trong C hoặc Java. – Helio

Trả lời

9

Trong Python, modulo được tính theo hai quy tắc:

  • (a // b) * b + (a % b) == a, và
  • a % b có dấu hiệu tương tự như b.

Kết hợp điều này với thực tế là phân chia số nguyên làm tròn xuống (theo −∞) và hành vi kết quả được giải thích.

Nếu bạn làm -8 // 5, bạn sẽ nhận được -1,6 được làm tròn xuống, là -2. Nhân với 5 và bạn nhận được -10; 2 là số mà bạn phải thêm vào đó để lấy -8. Do đó, -8 % 5 là 2.

0

Khi bạn chia ints (-2/5) * 5 không không đánh giá để -2, vì nó sẽ trong đại số bạn đang sử dụng. Hãy thử chia nhỏ nó thành hai bước, trước tiên hãy đánh giá phần trong dấu ngoặc đơn.

  1. (-2/5) * 5 = (-1) * 5
  2. (-1) * 5 = -5

Lý do cho bước 1 là bạn đang làm int phân chia, mà trong python 2.x trả về tương đương với kết quả phân chia float làm tròn xuống số nguyên gần nhất.

Trong trăn 3 trở lên, 2/5 sẽ trả về một phao, xem PEP 238.

0

Kiểm tra this BetterExplained article và xem nhận xét của @ David (số 6) để biết những gì người khác đang nói đến.

Kể từ khi chúng tôi đang làm việc w/số nguyên, chúng tôi phân chia int trong đó, Python, tầng câu trả lời như trái ngược với C. Để biết thêm về điều này, hãy đọc Guido's article.

Đối với câu hỏi của bạn:

>>> 8 % 5 #B'coz (5*1) + *3* = 8 
3 
>>> -8 % 5 #B'coz (5*-2) + *2* = -8 
2 

Hy vọng rằng sẽ giúp. Nó làm tôi bối rối ngay từ đầu (nó vẫn vậy)! :)

3

Lý do đằng sau đây thực sự là định nghĩa toán học của least residue. Python tôn trọng định nghĩa này, trong khi ở hầu hết các ngôn ngữ lập trình khác, toán tử mô đun thực sự giống như toán tử 'reaminder after division'. Để tính số dư tối thiểu của -5 % 11, chỉ cần thêm 11 đến -5 cho đến khi bạn có được số nguyên dương trong khoảng [0,10] và kết quả là 6.

5

Trong Python, a // b được định nghĩa là tầng (a/b), trái ngược với hầu hết các ngôn ngữ khác trong đó phân chia số nguyên được định nghĩa là trunc (a/b). Có sự khác biệt tương ứng trong cách diễn giải của a % b = a - (a // b) * b.

Lý do cho điều này là định nghĩa của Python về toán tử % (và divmod) thường hữu ích hơn các ngôn ngữ khác. Ví dụ:

def time_of_day(seconds_since_epoch): 
    minutes, seconds = divmod(seconds_since_epoch, 60) 
    hours, minutes = divmod(minutes, 60) 
    days, hours = divmod(hours, 24) 
    return '%02d:%02d:%02d' % (hours, minutes, seconds) 

Với chức năng này, time_of_day(12345) trả về '03:25:45', như bạn mong đợi.

Nhưng thời gian là 12345 giây trước kỷ nguyên? Với định nghĩa của Python là divmod, time_of_day(-12345) trả về chính xác '20:34:15'.

Nếu chúng tôi xác định lại divmod để sử dụng định nghĩa C là /% thì sao?

def divmod(a, b): 
    q = int(a/b) # I'm using 3.x 
    r = a - b * q 
    return (q, r) 

Bây giờ, time_of_day(-12345) lợi nhuận '-3:-25:-45', mà không phải là một thời gian hợp lệ trong ngày. Nếu chức năng Python divmod chuẩn được triển khai theo cách này, bạn phải viết mã đặc biệt để xử lý các đầu vào âm. Nhưng với phân chia theo kiểu sàn, giống như ví dụ đầu tiên của tôi, nó chỉ hoạt động.

+1

Tôi chỉ sử dụng Python một chút, và không ấn tượng với nó, nhưng nó làm ấm trái tim tôi để thấy ít nhất một ngôn ngữ lập trình đang nắm giữ cho một toán tử phân chia có thể sử dụng được. Ví dụ về thời gian trong ngày của bạn thật tuyệt vời. Tôi đã thấy khiếu nại rằng toán tử mô đun Euclidian không hoạt động để trích xuất các chữ số từ số âm (ví dụ: -123% 10 sản lượng 7 mặc dù chữ số cuối cùng là 3). Mặt khác, một nhà điều hành phần còn lại kiểu C-năng suất -3 không thực sự tốt hơn. – supercat

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