Skip to content

Unary minus on a BigInt array element float-negates it (wrong value, silent) #9142

Description

@proggeramlug

Found while benchmarking BigInt division (#9141); reproduces on pristine main 653e886699, unrelated to that change.

Repro

const c = [2n ** 64n];
console.log(-c[0]);
result
node -18446744073709551616
perry -18446744073709552000

The perry value is the f64 rounding of 2^64 — the BigInt is being converted to a double and float-negated. Silent wrong value, no throw.

Characterization

  • Reading c[0] alone is correct (prints the exact BigInt).
  • -v where v is a plain local holding the same BigInt is correct.
  • Only unary minus applied directly to an array element mis-lowers.
  • An explicit bigint[] annotation does not help.

So the element read produces the right value and the unary-minus lowering picks the numeric path regardless of the operand's runtime type.

Why it matters

BigInt arrays are the normal representation for big-number tables (hash constants, crypto limbs, byte→BigInt lookup tables like TypeBox's). A silently-rounded negation in that code produces wrong results with no diagnostic.

Repro file: secret-tests/scratchpad/probe_q2.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions