Translate code with ChatGPT without changing negative-number behavior

When asking ChatGPT to translate code, specify the source and target language versions, input domain and exact expected results. Copying similar-looking operators can change behavior. Python's floor division and modulo do not match JavaScript's truncated division and remainder for negative integers, so a port that passes only positive cases can still assign negative offsets to the wrong bucket.

Start with the meaning of the pair

This original Python function divides an integer offset into fixed-width buckets. Width is a positive integer. The bucket is floored, and the position is always between zero and width minus one:

def bucket_position(offset, width):
    return offset // width, offset % width

With width 5, offset 6 becomes (1,1). Offset -1 becomes (-1,4): it belongs to the bucket starting at -5, four positions after that start. Every result must satisfy offset=bucket*width+position.

The Python expressions reference, checked October 24, 2026, defines floor division and the relationship with modulo. The ECMAScript specification defines the target arithmetic. These language rules, rather than the visual similarity of the operators, determine the port.

Reject a plausible direct substitution

A JavaScript port using Math.trunc(offset/width) and offset%width would return a zero bucket and position -1 for offset -1 and width 5. JavaScript's remainder retains the dividend's sign; it does not automatically supply the nonnegative position required here.

Use boundary fixtures that force this distinction:

Offset Width Bucket Position
6 5 1 1
0 5 0 0
-1 5 -1 4
-5 5 -1 0
-6 5 -2 4

Make the target numeric boundary explicit

This JavaScript Number implementation accepts safe integer offsets with absolute value at most 1,000,000,000 and widths from 1 through 1,000,000. The conservative bound keeps the example away from large-integer precision problems; it is an application contract, not a limitation claimed for Python.

function bucketPosition(offset, width) {
  if (!Number.isSafeInteger(offset) || Math.abs(offset) > 1_000_000_000 ||
      !Number.isSafeInteger(width) || width < 1 || width > 1_000_000) {
    throw new RangeError("outside the supported integer domain");
  }
  const bucket = Math.floor(offset / width);
  const position = offset - bucket * width;
  return [bucket === 0 ? 0 : bucket, position === 0 ? 0 : position];
}

The explicit zero normalization avoids exposing negative zero through the returned pair. The target returns an array in place of Python's tuple; callers need to accept that intentional interface translation.

If the real source accepts arbitrary-size integers, this bounded Number version is insufficient. Design an appropriate integer representation and division rule before porting those callers. Do not silently truncate values or weaken the source domain.

Give ChatGPT the parity checks

Translate this Python bucket-position function to JavaScript.
Source and target runtimes/versions: [ENTER]
Source code and relevant callers: [PASTE]
Meaning: offset=bucket*width+position; 0<=position<width.
Width is positive. State how negative offsets behave.
Approved target numeric domain and return interface: [ENTER]
Parity fixtures, including -1,-5,-6 with width 5: [PASTE]

Explain source/target arithmetic differences before giving code.
Preserve the stated behavior throughout the approved input domain.
Flag unsupported source inputs instead of silently narrowing them.
Give runnable parity checks and invalid-domain checks.
Separate predicted results from tests actually executed.

OpenAI's prompting guidance supports adding context and boundaries that affect the answer. For a port, the input domain and operator semantics carry more information than a general instruction to use idiomatic syntax.

Check both the pair and its identity

Execute the source and target with the same approved fixtures. Compare both returned components, then check the reconstruction identity and position bounds. Include a zero-width rejection and values just outside the target contract. Passing the reconstruction identity alone is insufficient: a negative position can still reconstruct the original offset.

The Python guide handles writing a first local script; the JavaScript guide explains a browser execution-order example. For this port, retain the negative-input fixtures beside both implementations and update callers only after the agreed semantic comparison passes.

Keep reading