จำนวนเต็มกับส่วนที่เหลือใน JavaScript?


929

ในJavaScriptฉันจะได้รับ:

  1. จำนวนครั้งทั้งหมดที่จำนวนเต็มที่กำหนดให้เป็นอีกตัวหนึ่ง
  2. ที่เหลือ?

คำตอบ:


1239

สำหรับจำนวนyและตัวหารบางตัวxคำนวณความฉลาดทาง ( quotient) และส่วนที่เหลือ ( remainder) เป็น:

var quotient = Math.floor(y/x);
var remainder = y % x;

84
% ทำงานกับการลอยใน JavaScript (ซึ่งแตกต่างจากภาษาอื่น ๆ ) ซึ่งอาจไม่ต้องการ: 3.5 % 2ประเมินเป็น 1.5 ตรวจสอบให้แน่ใจว่าได้จัดการ (แยกวิเคราะห์พื้น ฯลฯ ) ตามต้องการ

16
ส่วนประกอบสำคัญของ -4.5 ในวิชาคณิตศาสตร์คือ -5 เนื่องจาก -5 เป็น "จำนวนอินทิกรัลจำนวนสูงสุดที่เป็นไปได้ที่ยังคงต่ำกว่า -4.5"
Toughy

9
อย่างไรก็ตามสิ่งที่คุณตัดสินใจที่จะทำเกี่ยวกับจำนวนลบมันควรจะสอดคล้องกันทั้งเชาวน์และส่วนที่เหลือ การใช้floorและ%ร่วมกันไม่สอดคล้องกันในวิธีนั้น ใช้อย่างใดอย่างหนึ่งtruncแทนfloor(จึงอนุญาตให้มีส่วนที่เหลือเป็นลบ) หรือใช้การลบเพื่อให้ได้ส่วนที่เหลือ ( rem = y - div * x)
Mark Reed

7
1. ถ้าคุณกำลังจะคำนวณส่วนที่เหลือremต่อไปคุณจะได้รับผลหารได้เร็วขึ้นโดยไม่ต้องพื้น:div (y - rem) / x2. โดยวิธีการดำเนินการตามคำนิยามแบบโมดูโลแนะนำโดนัลด์ของ Knuth (เครื่องหมายตรง-หารไม่เหลือคือยุคลิดโมดูลัสหรือจาวาสคริปต์เครื่องหมายตรงเงินปันผล) เป็นสิ่งที่เราสามารถรหัสใน JavaScript function mod (a, n) { return a % n + (Math.sign(a) !== Math.sign(n) ? n : 0); }เป็น
Aaron Mansheim

1
-9 / 2 = -4.5 จากนั้นคุณใช้พื้น -4.5 ซึ่งก็คือ -5 โปรดจำไว้ว่า -5 น้อยกว่า -4.5 และการดำเนินการพื้นถูกกำหนดเป็นจำนวนเต็มที่มากที่สุดน้อยกว่าค่าที่กำหนด
Mark Reed

371

ฉันไม่มีความเชี่ยวชาญในผู้ประกอบการระดับบิต แต่นี่เป็นอีกวิธีในการรับจำนวนทั้งหมด:

var num = ~~(a / b);

สิ่งนี้จะทำงานอย่างถูกต้องสำหรับจำนวนลบเช่นกันในขณะที่Math.floor()จะปัดไปในทิศทางที่ไม่ถูกต้อง

ดูเหมือนว่าถูกต้องเช่นกัน:

var num = (a / b) >> 0;

84
อีกหนึ่งซึ่งมีวัตถุประสงค์ฉันเพิ่งใช้เวลา 20 นาทีล่าสุดพยายามที่จะคิดออกa/b | 0
BlueRaja - Danny Pflughoeft

18
@ user113716 การดำเนินการ @BlueRaja Bitwise สมเหตุสมผลเฉพาะกับประเภทจำนวนเต็มและ JS (แน่นอน) รู้ดีว่า ~~int, int | 0และint >> 0ไม่ได้ปรับเปลี่ยนการโต้เถียงเริ่มต้น แต่ให้ล่ามผ่านส่วนหนึ่งในการประกอบการ
Aleksei Zabrodskii

15
floorแทบจะปัดไปในทิศทางที่ไม่ถูกต้องตามชื่อ - ไม่ใช่ทิศทางที่คนทั่วไปต้องการ!
Mark K Cowan

19
นั่นคือ buu buu a = 12447132275286670000; b = 128 Math.floor(a/b)-> 97243220900677100และ->~~(a/b) -1231452688
Mirek Rusin

7
ระวังด้วยความสำคัญ ~~(5/2) --> 2เช่นเดียว(5/2)>>0 --> 2แต่ในขณะที่~~(5/2) + 1 --> 3 เป็นตัวเลือกที่ดีเพราะลำดับความสำคัญเหมาะสมกว่า ~~(5/2)>>0 + 1 --> 1~~
timkay

217

ฉันทำการทดสอบความเร็วบน Firefox

-100/3             // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34,       0.5016 millisec
~~(-100/3)         // -33,       0.3619 millisec
(-100/3>>0)        // -33,       0.3632 millisec
(-100/3|0)         // -33,       0.3856 millisec
(-100-(-100%3))/3  // -33,       0.3591 millisec

/* a=-100, b=3 */
a/b                // -33.33..., 0.4863 millisec
Math.floor(a/b)    // -34,       0.6019 millisec
~~(a/b)            // -33,       0.5148 millisec
(a/b>>0)           // -33,       0.5048 millisec
(a/b|0)            // -33,       0.5078 millisec
(a-(a%b))/b        // -33,       0.6649 millisec

ข้างต้นอ้างอิงจากการทดลอง 10 ล้านครั้งสำหรับแต่ละครั้ง

สรุป:ใช้(a/b>>0)(หรือ(~~(a/b))หรือ(a/b|0)) เพื่อให้ได้ประสิทธิภาพเพิ่มขึ้นประมาณ 20% นอกจากนี้ยังเก็บไว้ในใจว่าพวกเขาจะไม่สอดคล้องกันทั้งหมดที่มีเมื่อMath.floora/b<0 && a%b!=0


54
โปรดทราบว่าการเพิ่มประสิทธิภาพการแบ่งจำนวนเต็มสำหรับความเร็วจะทำให้ความรู้สึกเท่านั้นถ้าคุณกำลังทำมันมาก ในกรณีอื่น ๆ ฉันขอแนะนำให้เลือกหนึ่งที่ง่ายที่สุด (แล้วแต่ว่าคุณและเพื่อนร่วมงานของคุณจะดูแบบไหน)
mik01aj

7
@ m01 เห็นด้วยอย่างยิ่ง - มีวิธีมากเกินไปที่จะมุ่งเน้นสิ่งต่าง ๆ เช่นออนไลน์
JonnyRaa

2
@ m01 แต่สิ่งใดที่ยากกว่า: การเรียนรู้เกี่ยวกับMath.floorฟังก์ชั่น API อื่น ๆ ที่รู้~เท่าทันหรือเรียนรู้เกี่ยวกับตัวดำเนินการ(bitwise-not) และการทำงานของ bitwise ใน JS แล้วเข้าใจถึงผลกระทบของตัวหนอนสองตัวหรือไม่
Stijn de Witt

11
ถ้าเพื่อนร่วมงานของคุณไม่ได้เขียนโปรแกรมชิปในแอสเซมเบลอร์พวกเขาน่าจะเข้าใจMath.floorดีกว่า และแม้ว่าจะไม่เป็นเช่นนี้อันนี้เป็น googleable
mik01aj

2
@ MarkGreen ใช่ แต่เพียงแค่ต้องการทำเช่นนั้นไม่ได้หมายความว่าคุณควรเขียนมันในรูปแบบแปลก ๆ เพียงเพราะมันเกิดขึ้นเร็วที่สุดโดยไม่มีเหตุผล - รหัสชัดเจนโดยทั่วไปควรเป็นข้อกังวลแรกของคุณ การทดสอบเหล่านี้อาจไม่มีความหมายอย่างสมบูรณ์หลังจากการเปลี่ยนแปลงภาษาและในเบราว์เซอร์ที่แตกต่างกัน - คุณจะต้องทำการโปรไฟล์เพื่อดูว่าแอปพลิเคชันของคุณช้าเพียงใด เป็นไปได้ยากที่จะเป็นวิธีหารจำนวนเต็มของคุณเว้นแต่ว่าคุณจะปรับปรุงสิ่งอื่น ๆ
JonnyRaa

150

ES6 แนะนำMath.truncวิธีการใหม่ วิธีนี้ช่วยแก้ไขคำตอบของ @ MarkElliotเพื่อให้สามารถใช้กับจำนวนลบได้เช่นกัน:

var div = Math.trunc(y/x);
var rem = y % x;

โปรดทราบว่าMathวิธีการที่มีความได้เปรียบกว่าผู้ประกอบการระดับบิตที่พวกเขาทำงานกับตัวเลขมากกว่า 2 วันที่ 31


var y = 18014398509481984; var x = 5; div =? - บั๊ก?
4esn0k

4
@ 4esn0k ไม่ใช่ข้อผิดพลาด หมายเลขของคุณมีตัวเลขมากเกินไปคุณไม่สามารถแม่นยำได้มากนักในรูปแบบไบนารี 64 บิตหมายเลข IEEE 754 ตัวอย่างเช่น18014398509481984 == 18014398509481985.
Oriol

18014398509481984 == 2 ** 54 และฉันใช้หมายเลขนี้เป็นพิเศษเพราะมันถูกแสดงในรูปแบบไบนารี 64 อย่างแน่นอน และคำตอบก็เหมือนกัน
4esn0k

1
ฉันคิดว่าตัวเลือกนั้นง่าย: คุณต้องการการสนับสนุนสำหรับตัวเลขที่มีการลงนามสูงสุด 32 บิตหรือไม่ ~~(x/y)ใช้ ต้องการรองรับตัวเลขที่ใหญ่กว่ามากถึง 54 บิตหรือไม่? ใช้Math.truncถ้าคุณมีมันหรือMath.floorอย่างอื่น (ถูกต้องสำหรับจำนวนลบ) ต้องการรองรับตัวเลขที่ยิ่งใหญ่กว่านี้ไหม? ใช้ไลบรารีจำนวนมาก
Stijn de Witt

4
สำหรับ rubyists ที่นี่จาก google ในการค้นหาdivmodคุณสามารถใช้มันเช่น:function divmod(x, y) { var div = Math.trunc(x/y); var rem = x % y; return [div, rem]; }
Alex Moore-Niemi

29
var remainder = x % y;
return (x - remainder) / y;

1
รุ่นนี้โชคไม่ดีที่การทดสอบล้มเหลวเมื่อ x = -100 เพราะมันคืนค่า -34 แทนที่จะเป็น -33
ซามูเอล

1
แล้ว "var x = 0.3; var y = 0.01;" ? (ขอบคุณgithub.com/JuliaLang/julia/issues/4156#issuecomment-23324163 )
4esn0k

ที่จริงแล้ว @Samuel ที่มีค่าลบวิธีนี้จะส่งกลับผลลัพธ์ที่ถูกต้องหรืออย่างน้อยก็คืนค่าเดียวกันกับวิธีที่ใช้Math.trunc:) ฉันตรวจสอบด้วย 100,3; -100,3; 100, -3 และ -100, -3 แน่นอนว่าเวลาผ่านไปนานมากแล้วตั้งแต่ความคิดเห็นและสิ่งต่าง ๆ ของคุณเปลี่ยนไป
Marjan Venema

19

ปกติฉันจะใช้:

const quotient =  (a - a % b) / b;
const remainder = a % b;

มันอาจจะไม่หรูหราที่สุด แต่ก็ใช้ได้ดี


1
ทางออกที่ดีเพราะมันหลีกเลี่ยงความน่าเกลียดของการแยกหรือตัดทุ่นลอย
Dem Pilafian

6
หากคุณต้องการทั้งความฉลาดทางและส่วนที่เหลือให้คำนวณส่วนที่เหลือก่อนจากนั้นนำค่านั้นมาใช้ใหม่ในนิพจน์สำหรับความฉลาดทางนั้น ได้แก่ quotient = (a - ส่วนที่เหลือ) / b;
gb96

2
เหลือ = a% b; quotient = (a - ส่วนที่เหลือ) / b;
Zv_oDD

16

คุณสามารถใช้ฟังก์ชั่นparseIntเพื่อให้ได้ผลลัพธ์ที่ถูกตัดทอน

parseInt(a/b)

ในการรับเศษเหลือให้ใช้ตัวดำเนินการ mod:

a%b

parseInt มีข้อผิดพลาดบางอย่างกับสตริงเพื่อหลีกเลี่ยงการใช้พารามิเตอร์ radix กับฐาน 10

parseInt("09", 10)

ในบางกรณีการแสดงสตริงของตัวเลขอาจเป็นสัญกรณ์ทางวิทยาศาสตร์ในกรณีนี้การแยกวิเคราะห์จะให้ผลลัพธ์ที่ไม่ถูกต้อง

parseInt(100000000000000000000000000000000, 10) // 1e+32

การโทรนี้จะสร้างผลลัพธ์ 1 รายการ


7
parseIntควรหลีกเลี่ยงเมื่อเป็นไปได้ นี่คือคำเตือนของ Douglas Crockford: "ถ้าอักขระตัวแรกของสตริงเป็น 0 สตริงจะถูกประเมินในฐาน 8 แทนฐาน 10 ในฐาน 8, 8 และ 9 ไม่ใช่ตัวเลขดังนั้น parseInt (" 08 ") และ parseInt ("09") สร้าง 0 เป็นผลลัพธ์ข้อผิดพลาดนี้ทำให้เกิดปัญหาในโปรแกรมที่แยกวันที่และเวลาโชคดีที่ parseInt สามารถรับพารามิเตอร์ radix ดังนั้น parseInt ("08", 10) จะสร้าง 8 ฉันขอแนะนำให้คุณเสมอ ระบุพารามิเตอร์ radix " archive.oreilly.com/pub/a/javascript/excerpts/…
พลัง

3
ในการแบ่งฉันคาดหวังว่าจะได้รับตัวเลขไม่ใช่สตริง แต่นี่เป็นจุดที่ดี
Édipo Costa Rebouças

2
@Powers ดังนั้นเพิ่ม radix เขาไม่พูดว่าparseIntควรหลีกเลี่ยง; เพียงแค่มี gotchas บางอย่างที่ต้องระวัง คุณต้องระวังสิ่งเหล่านี้และเตรียมพร้อมรับมือ
ไม่มี

2
ไม่ต้องโทรparseIntด้วยอาร์กิวเมนต์หมายเลข parseIntควรแยกสตริงที่เป็นตัวเลขบางส่วนไม่ใช่ตัดทอนหมายเลข
Oriol

1
เพียงเพราะสิ่งต่าง ๆ ไม่ได้หมายถึงการใช้วิธีการบางอย่าง แต่ไม่ได้หมายความว่าคุณไม่ควร คำตอบนี้ใช้ได้ผล
Fregante

6

จาวาสคริปต์คำนวณพื้นของจำนวนลบและส่วนที่เหลือของตัวเลขที่ไม่ใช่จำนวนเต็มตามนิยามทางคณิตศาสตร์สำหรับพวกเขา

FLOOR ถูกกำหนดเป็น "จำนวนเต็มที่มากที่สุดซึ่งเล็กกว่าพารามิเตอร์" ดังนั้น:

  • ตัวเลขบวก: FLOOR (X) = ส่วนจำนวนเต็มของ X;
  • จำนวนลบ: FLOOR (X) = ส่วนจำนวนเต็มของ X ลบ 1 (เพราะมันจะต้องมีขนาดเล็กกว่าพารามิเตอร์เช่นลบมากขึ้น!)

REMAINDER ถูกกำหนดให้เป็น "ส่วนที่เหลือ" ของส่วน (Euclidean เลขคณิต) เมื่อเงินปันผลไม่ใช่จำนวนเต็มผลหารมักจะไม่ใช่จำนวนเต็มเช่นไม่มีเศษ แต่ถ้าหารหารด้วยจำนวนเต็ม (และนั่นคือสิ่งที่เกิดขึ้นเมื่อมีคนพยายามหาเศษหรือโมดูลัสของ a จำนวนจุดลอยตัว) จะมีจำนวนที่ไม่ใช่ "เหลือ" อย่างชัดเจน

JavaScript คำนวณทุกอย่างตามที่คาดไว้ดังนั้นโปรแกรมเมอร์จะต้องระมัดระวังในการถามคำถามที่เหมาะสม (และผู้คนควรระมัดระวังในการตอบคำถามที่ถาม!) คำถามแรกของ Yarin ไม่ใช่ "การหารจำนวนเต็มของ X ด้วย Y คืออะไร แต่ แทน "จำนวนครั้งทั้งหมดที่จำนวนเต็มที่กำหนดไปยังอีกรายการหนึ่ง" สำหรับตัวเลขบวกคำตอบจะเหมือนกันสำหรับทั้งคู่ แต่ไม่ใช่สำหรับจำนวนลบเนื่องจากการหารจำนวนเต็ม (การหารด้วยตัวหาร) จะน้อยกว่าจำนวนครั้งที่ตัวหาร (ตัวหาร) "-1" (การหาร) กล่าวอีกนัยหนึ่งชั้นจะคืนคำตอบที่ถูกต้องสำหรับการหารจำนวนเต็มของจำนวนลบ แต่ Yarin ไม่ได้ถามอย่างนั้น!

gammax ตอบถูกต้องรหัสนั้นทำงานตามที่ Yarin ถาม ในทางตรงกันข้ามซามูเอลผิดเขาไม่ได้ทำคณิตศาสตร์ฉันเดาหรือเขาจะได้เห็นว่ามันใช้งานได้ (เช่นกันเขาไม่ได้พูดว่าตัวหารของตัวอย่างของเขาเป็นอย่างไร แต่ฉันหวังว่ามันจะเป็น 3):

ส่วนที่เหลือ = X% Y = -100% 3 = -1

GoesInto = (X - ส่วนที่เหลือ) / Y = (-100 - -1) / 3 = -99 / 3 = -33

โดยวิธีการที่ฉันทดสอบรหัสบน Firefox 27.0.1 มันทำงานได้ตามที่คาดหวังกับจำนวนบวกและลบและยังมีค่าที่ไม่ใช่จำนวนเต็มทั้งสำหรับเงินปันผลและตัวหาร ตัวอย่าง:

-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079

ใช่ฉันสังเกตเห็นว่ามีปัญหาความแม่นยำ แต่ฉันไม่มีเวลาตรวจสอบ (ฉันไม่รู้ว่าเป็นปัญหากับ Firefox, Windows 7 หรือกับ FPU ของ CPU ของฉัน) สำหรับคำถามของ Yarin ซึ่งเกี่ยวข้องกับจำนวนเต็มเท่านั้นรหัสของ gammax นั้นทำงานได้อย่างสมบูรณ์


5

Math.floor(operation) ส่งคืนค่าที่ปัดเศษลงของการดำเนินการ

ตัวอย่าง 1 เซนต์คำถาม:

var x = 5;
var y = 10.4;
var z = Math.floor(x + y);

console.log(z);

คอนโซล:

15

ตัวอย่าง 2 ครั้งคำถาม:

var x = 14;
var y = 5;
var z = Math.floor(x%y);

console.log(x);

คอนโซล:

4


2

การคำนวณจำนวนหน้าสามารถทำได้ในขั้นตอนเดียว: Math.ceil (x / y)


ฉันไม่เห็นวิธีการนี้ให้ส่วนที่เหลือ
Paul Rooney

1

ความคิดเห็นของAlex Moore-Niemiเป็นคำตอบ:

สำหรับ Rubyists ที่นี่จาก Google ในการค้นหาdivmodคุณสามารถใช้มันได้เช่น:

function divmod(x, y) {
  var div = Math.trunc(x/y);
  var rem = x % y;
  return [div, rem];
}

ผลลัพธ์:

// [2, 33]

2
โดยปกติจะdivmodใช้การแบ่งพื้น ( Math.floor) ซึ่งแตกต่างจากการตัดทอน ( Math.trunc) เมื่อมีการลบจำนวนที่เกี่ยวข้อง นี่เป็นกรณีสำหรับแพ็คเกจNPMdivmod , Rubydivmod , SWI-Prologdivmodและการใช้งานอื่น ๆ อีกมากมายเช่นกัน
Palec

การตัดส่วนให้ผลลัพธ์ที่ดูเป็นธรรมชาติมากกว่าการแบ่งแบบพื้น แต่ความเข้ากันได้นั้นสำคัญกว่า IMO อาจมีเหตุผลทางคณิตศาสตร์หรือประสิทธิภาพในการใช้การแบ่งพื้น โปรดทราบว่าโดยปกติแล้วจะdivmodมีอยู่เนื่องจากมีการทำงานสองครั้งเร็วเท่ากับการคำนวณการดำเนินการทั้งสองแยกจากกัน การจัดให้มีฟังก์ชันดังกล่าวโดยไม่มีผลประโยชน์ด้านประสิทธิภาพนี้อาจทำให้เกิดความสับสน
Palec

1

หากคุณเพียงแค่หารด้วยพลังของสองคุณสามารถใช้ตัวดำเนินการระดับบิต:

export function divideBy2(num) {
  return [num >> 1, num & 1];
}

export function divideBy4(num) {
  return [num >> 2, num & 3];
}

export function divideBy8(num) {
  return [num >> 3, num & 7];
}

(อันแรกคือความฉลาดทาง, ส่วนที่สองที่เหลือ)


โดยทั่วไปแล้วfunction divideByPowerOf2(num, exponent) { return [num >> exponent, num & ((1 << exponent) - 1)]; }.
Palec

0

คุณสามารถใช้ ternary เพื่อตัดสินใจว่าจะจัดการค่าจำนวนเต็มบวกและลบได้เช่นกัน

var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1

หากจำนวนเป็นบวกทั้งหมดจะดี ถ้าตัวเลขเป็นลบมันจะบวก 1 เพราะ Math.floor จัดการกับเนกาทีฟ


0

สิ่งนี้จะตัดทอนเป็นศูนย์เสมอ ไม่แน่ใจว่ามันสายเกินไปหรือไม่ แต่นี่มันจะไป:

function intdiv(dividend, divisor) { 
    divisor = divisor - divisor % 1;
    if (divisor == 0) throw new Error("division by zero");
    dividend = dividend - dividend % 1;
    var rem = dividend % divisor;
    return { 
        remainder: rem, 
        quotient: (dividend - rem) / divisor
    };
}

0

หากคุณต้องการคำนวณส่วนที่เหลือสำหรับจำนวนเต็มขนาดใหญ่มากซึ่งรันไทม์ของ JS ไม่สามารถแสดงเช่นนั้น (จำนวนเต็มใด ๆ ที่มากกว่า 2 ^ 32 จะแสดงเป็นทุ่นและดังนั้นจึงสูญเสียความแม่นยำ) คุณต้องทำเคล็ดลับบางอย่าง

สิ่งนี้มีความสำคัญอย่างยิ่งสำหรับการตรวจสอบตัวเลขเช็คจำนวนมากซึ่งมีอยู่ในชีวิตประจำวันของเรา (หมายเลขบัญชีธนาคารบัตรเครดิต ... )

ก่อนอื่นคุณต้องใช้หมายเลขของคุณเป็นสตริง (มิฉะนั้นคุณสูญเสียความแม่นยำไปแล้วและส่วนที่เหลือไม่สมเหตุสมผล)

str = '123456789123456789123456789'

ตอนนี้คุณต้องแบ่งสตริงของคุณเป็นชิ้นส่วนเล็ก ๆ น้อย ๆ พอเพื่อให้การต่อส่วนที่เหลือใด ๆ และชิ้นส่วนของสตริงสามารถพอดีกับ 9 หลัก

digits = 9 - String(divisor).length

เตรียมนิพจน์ทั่วไปเพื่อแยกสตริง

splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')

ตัวอย่างเช่นถ้าdigitsเป็น 7 regexp คือ

/.{1,7}(?=(.{7})+$)/g

มันตรงกับสตริงย่อยที่ไม่มีความยาวสูงสุด 7 ซึ่งตามมา ((?=...)เป็น lookahead เชิงบวก) โดยจำนวนของอักขระที่เป็นทวีคูณของ 7 ตัว 'g' คือการทำให้นิพจน์วิ่งผ่านสตริงทั้งหมดไม่ใช่หยุดที่คู่แรก

ตอนนี้แปลงแต่ละส่วนเป็นจำนวนเต็มและคำนวณเศษที่เหลือด้วยreduce(บวกกลับเศษเหลือก่อนหน้า - หรือ 0 - คูณด้วยกำลังที่ถูกต้อง 10):

reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor

สิ่งนี้จะทำงานได้เนื่องจากอัลกอริทึมส่วนที่เหลือ "การลบ":

n mod d = (n - kd) mod d

ซึ่งอนุญาตให้แทนที่ 'ส่วนเริ่มต้น' ใด ๆ ของการแทนทศนิยมของตัวเลขด้วยส่วนที่เหลือโดยไม่ส่งผลกระทบต่อส่วนที่เหลือสุดท้าย

รหัสสุดท้ายจะมีลักษณะดังนี้:

function remainder(num, div) {
  const digits = 9 - String(div).length;
  const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
  const mult = Math.pow(10, digits);
  const reducer = (rem, piece) => (rem * mult + piece) % div;

  return str.match(splitter).map(Number).reduce(reducer, 0);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.