Introduction
Computing element-wise modulo between two arrays of 64-bit integers means calculating A[i] % B[i] for each index. In C/C++, use a simple loop or SIMD intrinsics for performance. In Python, NumPy's np.mod(A, B) or A % B handles this vectorized. In Java, use Math.floorMod for consistent behavior with negative numbers. The key concerns are division-by-zero when any element of the divisor array is zero, the sign of the result with negative operands, and overflow safety with 64-bit values.
Basic Element-Wise Modulo
Given arrays A = [a0, a1, a2, a3] and B = [b0, b1, b2, b3], the result is R = [a0 % b0, a1 % b1, a2 % b2, a3 % b3].
A = [55, 234, 91987654321, 152]
B = [5, 20, 123456789, 10]
R = [0, 14, 87730983, 2]
C Implementation
1#include <stdio.h>
2#include <stdint.h>
3#include <stdbool.h>
4
5bool array_mod(const int64_t a[], const int64_t b[], int64_t result[], int len) {
6 for (int i = 0; i < len; i++) {
7 if (b[i] == 0) {
8 return false; // Division by zero
9 }
10 result[i] = a[i] % b[i];
11 }
12 return true;
13}
14
15int main() {
16 int64_t a[] = {55, 234, 91987654321LL, 152};
17 int64_t b[] = {5, 20, 123456789, 10};
18 int64_t result[4];
19
20 if (array_mod(a, b, result, 4)) {
21 for (int i = 0; i < 4; i++) {
22 printf("%lld %% %lld = %lld\n", a[i], b[i], result[i]);
23 }
24 }
25 // 55 % 5 = 0
26 // 234 % 20 = 14
27 // 91987654321 % 123456789 = 87730983
28 // 152 % 10 = 2
29 return 0;
30}
In C/C++, the % operator for integers performs truncated division — the result has the sign of the dividend. For int64_t, no overflow occurs because modulo cannot produce a value larger than the operands.
C++ with SIMD (AVX2)
1#include <immintrin.h>
2#include <cstdint>
3#include <iostream>
4
5// Note: AVX2 does not have native 64-bit integer division/modulo
6// This falls back to scalar operations
7void array_mod_64(const int64_t* a, const int64_t* b, int64_t* result, int len) {
8 // For 64-bit modulo, SIMD does not help — no hardware div instruction
9 // Process scalar
10 for (int i = 0; i < len; i++) {
11 result[i] = a[i] % b[i];
12 }
13}
14
15// For 32-bit arrays, SIMD can parallelize using reciprocal approximation
16// but 64-bit integer division has no SIMD support on x86
Most SIMD instruction sets (SSE, AVX2, AVX-512) lack integer division/modulo instructions. For 64-bit integers, scalar code is the only option on x86. The compiler may auto-optimize when the divisor is a compile-time constant.
Python with NumPy
1import numpy as np
2
3a = np.array([55, 234, 91987654321, 152], dtype=np.int64)
4b = np.array([5, 20, 123456789, 10], dtype=np.int64)
5
6# Element-wise modulo — vectorized, runs in C
7result = a % b
8# Or equivalently:
9result = np.mod(a, b)
10
11print(result)
12# [ 0 14 87730983 2]
13
14# Works with large arrays efficiently
15a_large = np.random.randint(1, 10**15, size=1000000, dtype=np.int64)
16b_large = np.random.randint(1, 10**9, size=1000000, dtype=np.int64)
17result_large = a_large % b_large # ~2ms for 1M elements
NumPy's % operator is vectorized and runs element-wise in compiled C code. For arrays with millions of elements, this is orders of magnitude faster than a Python loop.
Python: NumPy vs Python Modulo Sign
1import numpy as np
2
3# Python % always returns non-negative for positive divisor
4print(-7 % 3) # 2 (Python convention)
5
6# NumPy % follows the same convention
7print(np.mod(-7, 3)) # 2
8
9# C/C++ % follows truncated division (sign of dividend)
10# -7 % 3 = -1 in C
11
12# To get C-style truncated modulo in NumPy:
13print(np.fmod(-7, 3)) # -1.0 (matches C behavior)
14
15a = np.array([-7, -10, 15, -3], dtype=np.int64)
16b = np.array([3, 4, 7, 2], dtype=np.int64)
17
18print(np.mod(a, b)) # [2, 2, 1, 1] — Python/floored convention
19print(np.fmod(a, b)) # [-1, -2, 1, -1] — C/truncated convention
Java Implementation
1public class ArrayMod {
2 public static long[] elementWiseMod(long[] a, long[] b) {
3 if (a.length != b.length) {
4 throw new IllegalArgumentException("Arrays must be same length");
5 }
6
7 long[] result = new long[a.length];
8 for (int i = 0; i < a.length; i++) {
9 if (b[i] == 0) {
10 throw new ArithmeticException("Division by zero at index " + i);
11 }
12 result[i] = a[i] % b[i]; // Truncated division (sign of dividend)
13 }
14 return result;
15 }
16
17 // For floored modulo (always non-negative for positive divisor)
18 public static long[] elementWiseFloorMod(long[] a, long[] b) {
19 long[] result = new long[a.length];
20 for (int i = 0; i < a.length; i++) {
21 result[i] = Math.floorMod(a[i], b[i]);
22 }
23 return result;
24 }
25
26 public static void main(String[] args) {
27 long[] a = {55, 234, 91987654321L, 152};
28 long[] b = {5, 20, 123456789, 10};
29
30 long[] result = elementWiseMod(a, b);
31 // [0, 14, 87730983, 2]
32
33 // Negative number behavior
34 System.out.println(-7 % 3); // -1 (Java truncated)
35 System.out.println(Math.floorMod(-7, 3)); // 2 (floored)
36 }
37}
JavaScript Implementation
1const a = [55n, 234n, 91987654321n, 152n]; // BigInt for 64-bit
2const b = [5n, 20n, 123456789n, 10n];
3
4const result = a.map((val, i) => {
5 if (b[i] === 0n) throw new Error(`Division by zero at index ${i}`);
6 return val % b[i];
7});
8
9console.log(result); // [0n, 14n, 87730983n, 2n]
10
11// Standard Number type is 64-bit float — loses precision for large integers
12// Always use BigInt for exact 64-bit integer arithmetic
13console.log(91987654321 % 123456789); // May lose precision
14console.log(91987654321n % 123456789n); // 87730983n (exact)
JavaScript's Number type is a 64-bit float with only 53 bits of integer precision. For values exceeding Number.MAX_SAFE_INTEGER (2^53 - 1), use BigInt for exact modulo.
Handling Division by Zero
1import numpy as np
2
3a = np.array([10, 20, 30, 40], dtype=np.int64)
4b = np.array([3, 0, 7, 5], dtype=np.int64)
5
6# NumPy raises a warning and returns 0 for division by zero
7# np.mod(a, b) -> RuntimeWarning: divide by zero
8
9# Safe approach: mask zeros
10mask = b != 0
11result = np.zeros_like(a)
12result[mask] = a[mask] % b[mask]
13print(result) # [1, 0, 2, 0]
14
15# Or use np.where
16result = np.where(b != 0, a % b, 0)
Common Pitfalls
Division by zero: If any element in the divisor array is zero, the modulo operation crashes in C/Java (undefined behavior or ArithmeticException) or produces a warning in Python. Always validate the divisor array before computing, or mask out zero elements.
Sign of result varies by language: C, C++, and Java % use truncated division (result has the sign of the dividend: -7 % 3 = -1). Python % uses floored division (result matches the sign of the divisor: -7 % 3 = 2). Use Math.floorMod in Java or np.fmod in NumPy when cross-language consistency is needed.
Integer overflow with multiplication-based workarounds: Some modulo algorithms compute a - (a / b) * b. For large 64-bit values, (a / b) * b can overflow. The direct % operator does not have this problem — always prefer it.
JavaScript Number precision loss: JavaScript's Number cannot represent integers larger than 2^53 exactly. 91987654321 % 123456789 may produce an incorrect result because the operands lose precision. Use BigInt for 64-bit integer modulo.
No SIMD acceleration for 64-bit modulo: Unlike addition or multiplication, integer division/modulo has no SIMD hardware support on x86. SIMD-based approaches for modulo use multiplicative inverse approximations, which only work for 32-bit values or constant divisors.
Summary
Element-wise modulo computes A[i] % B[i] for each index across two arrays
In C/C++, use a simple loop — SIMD does not support 64-bit integer division
In Python, use np.mod(A, B) or A % B for vectorized computation
Watch for sign differences: Python % is floored, C/Java % is truncated
Always check for zero divisors before computing modulo
Use BigInt in JavaScript for exact 64-bit integer arithmetic