Bug 24844 – BigInt multiplication of 0 by integral (non-BigInt) type creates "-0" (negative zero)

Status
NEW
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2024-11-05T23:16:58Z
Last change time
2024-12-01T16:43:09Z
Assigned to
No Owner
Creator
Conor O'Brien
Moved to GitHub: phobos#10565 →

Comments

Comment #0 by conorobrien4god — 2024-11-05T23:16:58Z
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 (https://github.com/dlang/phobos/blob/9771a247f540ad0f16822bbffbb1724e218915ba/std/bigint.d#L268), which in turn is propagated to the non-mutating `opAssign` method (https://github.com/dlang/phobos/blob/9771a247f540ad0f16822bbffbb1724e218915ba/std/bigint.d#L524); 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); } }
Comment #1 by robert.schadek — 2024-12-01T16:43:09Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10565 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB