Bug 7006 – std.math.pow (integral, integral) crashes on negative exponents
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2011-11-25T13:12:07Z
Last change time
2020-01-03T09:05:17Z
Keywords
bootcamp, pull
Assigned to
No Owner
Creator
timon.gehr
Comments
Comment #0 by timon.gehr — 2011-11-25T13:12:07Z
It seems to be by design:
> if (n<0) return x/0; // Only support positive powers
But that does not make any sense. The results are well-defined if x!=0.
Comment #1 by clugdbug — 2011-11-27T23:36:13Z
(In reply to comment #0)
> It seems to be by design:
> > if (n<0) return x/0; // Only support positive powers
>
> But that does not make any sense. The results are well-defined if x!=0.
No, they aren't well defined. The result doesn't fit into an integer, unless x is 1 or -1. x^^n is always a bug if x is an integer other than +-1, and n is a negative integer.
The idea behind the division by zero error is that some processors (such as x86) also give a div by zero error on -1 / (-1 - int.max), because the result isn't representable as an integer. It's ugly though.
Now that we have proper range checking, we should be able to statically disallow it, and make n unsigned.
Comment #2 by timon.gehr — 2011-11-28T05:16:50Z
That is like saying 1/2 should give a div by zero error because the result does not fit in an integer and therefore it must always indicate a bug.
I want this:
assert(a ^^ -1 == 1/a);
This is only div by zero if a is zero.
(BTW: This does not give a div by zero error on my x86 machine, and I have no clue why you think it should: void main(){auto x = -1; x = x/(x-int.max);})
Comment #3 by clugdbug — 2011-12-02T05:01:01Z
(In reply to comment #2)
> That is like saying 1/2 should give a div by zero error because the result does
> not fit in an integer and therefore it must always indicate a bug.
Accidental use of integer division instead of floating point division is a very, very common bug.
> I want this:
>
> assert(a ^^ -1 == 1/a);
Why do you want that? Do you have any use cases where it's not a bug?
> This is only div by zero if a is zero.
>
>
> (BTW: This does not give a div by zero error on my x86 machine, and I have no
> clue why you think it should: void main(){auto x = -1; x = x/(x-int.max);})
Sorry, got it upside down. It's -int.max -1, divided by -1.
This generates a hardware division error. Depending on the OS, your OS may inspect the operands to determine if it is a div by zero, or this special case:
void main(){auto x = 1; x = (-1-int.max)/-x;}
Comment #4 by lt.infiltrator — 2014-03-19T22:09:46Z
So shall we mark this off as WONTFIX; or shall we look into negative exponents (and very coarse results of them)?
Comment #5 by cristiancreteanu06 — 2018-10-20T16:44:34Z
I provided a fix for the issue. However, I noticed that the return type of the function is an integer, which will make it impossible to have results different from 0 or 1 for negative exponents (2 to -2 is 0.5, but pow will return 0; 1 will be returned for powers of 1, of course). I believe that pow, no matter the arguments that are provided to it, should always return a floating point number.
Comment #6 by bugzilla — 2019-12-15T11:13:39Z
(In reply to Cristian Creteanu from comment #5)
> I believe that
> pow, no matter the arguments that are provided to it, should always return a
> floating point number.
That would mean pow(4294967290UL,2) == 18446744022169944064 instead of the correct 18446744022169944100...
If you really need negative powers of integeres, you should cast to floating point before using pow.
@berni44 created dlang/phobos pull request #7322 "Fix Issue 7006 - std.math.pow (integral, integral) crashes on negative exponents" fixing this issue:
- Fix Issue 7006 - std.math.pow (integral, integral) crashes on negative exponents
https://github.com/dlang/phobos/pull/7322
Comment #9 by timon.gehr — 2019-12-17T13:35:38Z
The expression (-1)^^x for negative x used to work correctly (by accident) due to constant folding. This constant folding for pow is going away: https://github.com/dlang/dmd/commit/0f2889c3aa9fba5534e754dade0cae574b636d55
Therefore, if this issue is not fixed, we will have a regression in the next compiler release.
Comment #10 by dlang-bot — 2020-01-03T09:05:17Z
dlang/phobos pull request #7322 "Fix Issue 7006 - std.math.pow (integral, integral) crashes on negative exponents" was merged into master:
- 357a4df94d62aeb45aa6feabac41adf2133502be by Bernhard Seckinger:
Fix Issue 7006 - std.math.pow (integral, integral) crashes on negative exponents
https://github.com/dlang/phobos/pull/7322