Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BigInt multiplication of 0 by integral (non-BigInt) type creates "-0" (negative zero) #10565

Open
dlangBugzillaToGithub opened this issue Nov 5, 2024 · 0 comments
Labels
Good First Issue Issue is easy to fix, good for new contributors Severity:Normal std.bigint

Comments

@dlangBugzillaToGithub
Copy link

dlangBugzillaToGithub commented Nov 5, 2024

conorobrien4god reported this on 2024-11-05T23:16:58Z

Transfered from https://issues.dlang.org/show_bug.cgi?id=24844

Description

Overview:

When multiplying a BigInt 0 by a negative, basic type (e.g. -1 and cast(byte)(-1)), the resulting BigInt is -0 (negative zero), which creates unexpected behavior.

It is likely a logical error in the isIntegral!y variant of the mutating opOpAssign method (

if (y == 0)
), which in turn is propagated to the non-mutating opAssign method (
r.opOpAssign!(op)(y);
); I imagine the linked conditional in opOpAssign should read something like if(y == 0 || data == 0UL) to prevent the sign being erroneously set for multiplication from 0, but I am not sure what the best modification should be.

The appearance of -0 (negative zero) appears to be a mistake, as evidenced by the resolved and fixed https://issues.dlang.org/show_bug.cgi?id=22771.

Steps to Reproduce:

Tested in the latest version of D (DMD64 D Compiler v2.109.1) and on https://run.dlang.io/

MWE demonstrating the bug, and when it occurs:

import std.stdio : writeln;
import std.bigint;

void main() {
  BigInt a = BigInt("0");                    // 0
  BigInt b = BigInt("-0");                   // 0
  BigInt c = BigInt("0") * -1;               // -0
  BigInt d = BigInt("0") * -42;              // -0
  BigInt e = BigInt("0"); e *= -1;           // -0
  BigInt f = BigInt(c);                      // -0
  BigInt g = BigInt("0") * cast(byte) -1;    // -0
  BigInt h = BigInt("0"); h *= BigInt("-1"); // 0
  BigInt i = BigInt("0"); i -= 2 * i;        // 0
  BigInt j = BigInt("0"); j = -j;            // 0
          
  BigInt[] test = [a,b,c,d,e,f,g,h,i,j];

  foreach(idx, t; test) {
    char id = "abcdefghij"[idx];
    writeln("`", id, "` = ", t);
    writeln("  Is `", id, "` negative? ", t < 0);
    writeln("  Is `", id, "` zero?     ", t == 0);
  }
}
@thewilsonator thewilsonator added std.bigint and removed OS:Windows Issues Specific to Windows Arch:x86 Issues specific to x86 P1 labels Dec 1, 2024
@thewilsonator thewilsonator added the Good First Issue Issue is easy to fix, good for new contributors label Jan 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue Issue is easy to fix, good for new contributors Severity:Normal std.bigint
Projects
None yet
Development

No branches or pull requests

2 participants