modulo operation
integer arrays
64-bit integers
array computation
programming techniques

Get modulo from two 4x64bit integer arrays

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

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

c
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)

cpp
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

python
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

python
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

java
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

javascript
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

python
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

Course illustration
Course illustration

All Rights Reserved.