[Issue 24844] New: BigInt multiplication of 0 by integral (non-BigInt) type creates "-0" (negative zero)
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Nov 5 23:16:58 UTC 2024
https://issues.dlang.org/show_bug.cgi?id=24844
Issue ID: 24844
Summary: BigInt multiplication of 0 by integral (non-BigInt)
type creates "-0" (negative zero)
Product: D
Version: D2
Hardware: x86
OS: Windows
Status: NEW
Severity: enhancement
Priority: P1
Component: phobos
Assignee: nobody at puremagic.com
Reporter: conorobrien4god at gmail.com
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);
}
}
--
More information about the Digitalmars-d-bugs
mailing list