Code JavaScript không tính chính xác được Modulo

Em đang làm 1 cái tool tính modulo theo công thức: x^n mod m = ?
Ví dụ: 4^8 mod 25 = 1 (chia lấy dư ấy ạ).

Bên C++ em dùng thuật toán bình phương và nhân, cả số mũ nhỏ và số mũ to đều tính khá ổn:
image
ví dụ: 613^520 mod 437 = 282 (đúng)

Tuy nhiên khi em áp dụng nó vào code JS với số mũ to thì lại tính sai.
code JS em để dưới comment ạ
ví dụ: 613^520 mod 437 = 4 (bị sai ấy ạ)

Mong các anh chị giúp. Em cảm ơn nhiều ạ !

Số trong JavaScript không phân biệt số thực - số nguyên đâu.

4 Likes

Không thấy code JS chỗ nào hết bạn :smiley:

2 Likes

Chưa nhìn code JS, nhưng kiểu Number trong JS không phân biệt số thưc, số nguyên nên n/2 sẽ trả về cả phần dư
==> Sửa lại thành Math.floor(n/2) để chỉ lấy phần nguyên xem sao bạn :))

3 Likes

Thay bằng n>>1 là được rồi :smiley:

4 Likes

Javascript thì ko nên tính toán số lớn vì nó ko tính đc.
Khoảng tính toán đc từ -(2^53 - 1) đến (2^53 - 1). Giá trị bạn đang tính nằm ngoài khoảng nên ra sai đáp số.

3 Likes

Hình như bây giờ có BigInt rồi thì phải :))

BigInt nhưng nó ko cho sài các phương thức của Number như Math.pow, nói chung code sẽ khá củ chuối với lại safari không hỗ trợ bigint. https://caniuse.com/#search=bigint
Theo mình trường hợp của bạn chủ topic biết code c++ thì code c++ rồi build sang WebAssembly. (nếu trên browser). https://caniuse.com/#search=WebAssembly
Gọi hàm bên js lấy kết quả là string mà hiển thị ok nhất.

5 Likes

code JS
image

Thế thì đúng là lỗi như vậy rồi :smiley:

3 Likes

Bạn Đào An trả lời đã chính xác rùi, mình chỉ phân tích thêm,

Đầu tiên bạn chạy thử hàm:
Number.MAX_SAFE_INTEGER ► “9007199254740991”

kế tiếp thử tính số của bạn:

613^520

151,273,534,200,268,181,332,054,551,538,130,696,252,137,405,404,538,276,513,978,876,825,707,805,820,801,868,296,281,923,359,764,400,545,693,773,239,839,242,150,268,583,808,600,299,087,413,755,637,223,323,559,023,314,849,996,028,349,675,288,148,915,285,604,454,306,851,460,206,928,086,441,553,807,518,969,094,662,122,966,528,405,375,248,045,578,616,137,169,717,295,033,393,435,427,155,291,033,430,973,382,185,680,544,668,087,937,019,182,456,923,604,225,323,068,824,321,006,397,585,998,405,800,857,079,411,643,823,134,268,746,804,590,137,542,748,659,182,213,376,996,204,748,476,184,292,309,005,144,598,439,079,562,647,460,671,466,452,756,046,013,433,357,901,847,546,803,544,111,261,329,324,258,550,848,107,155,713,090,736,720,456,786,264,368,539,341,161,966,189,241,060,960,684,530,636,994,303,124,125,806,595,701,233,216,697,912,633,760,510,448,323,041,775,891,049,418,745,047,036,503,468,557,483,700,852,617,430,927,834,851,204,204,556,188,457,133,582,214,545,590,853,928,968,499,621,019,244,071,045,213,122,920,696,245,959,074,573,833,425,213,115,639,730,525,326,960,591,582,383,389,012,377,411,160,167,702,956,796,548,780,219,683,052,497,180,330,024,960,302,538,015,905,057,491,021,907,352,918,492,504,965,608,937,159,009,146,727,101,491,228,061,892,026,162,077,795,857,607,834,411,642,461,638,956,860,824,654,672,786,117,816,212,077,426,447,808,898,179,186,001,494,353,109,739,118,313,441,070,689,869,530,887,815,144,803,134,475,883,672,512,823,344,816,546,404,876,248,988,404,964,056,351,585,994,468,427,332,536,636,528,993,039,590,676,780,951,676,050,036,512,885,931,334,581,725,582,331,548,780,595,764,847,796,810,926,794,821,867,673,168,234,626,754,929,842,376,381,879,785,890,106,593,232,451,979,150,501,072,115,968,613,328,701,158,837,686,516,648,737,235,965,223,292,200,997,250,584,760,398,686,114,644,566,361,399,900,690,226,083,772,146,278,320,995,190,118,247,533,792,456,289,934,047,098,881

Như vậy ta xác định được rằng không thể tính số lớn trên JavaScript.

Vậy nếu ta vẫn muốn tính toán big number trên JavaScript thì giải pháp là gì?
Đơn giản nhất là dùng JavaScript Big/Large Number Library, bạn có thể dễ dàng tìm thấy nó trên mạng ^-^
Còn bạn muốn tăng độ khó của Game :smile: thì có thể xem mấy cái Library trên GitHub rùi làm theo.

Hope help for you.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?