November 05 [Issue 24844] New: BigInt multiplication of 0 by integral (non-BigInt) type creates "-0" (negative zero) | ||||
---|---|---|---|---|
| ||||
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@puremagic.com Reporter: conorobrien4god@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); } } -- |
Copyright © 1999-2021 by the D Language Foundation