Jump to page: 1 28  
Page
Thread overview
issue 7006 - std.math.pow (integral, integral) crashes on negative exponents
Dec 15, 2019
berni44
Dec 15, 2019
Timon Gehr
Dec 15, 2019
berni44
Dec 16, 2019
Timon Gehr
Dec 16, 2019
mipri
Dec 16, 2019
Johannes Loher
Dec 16, 2019
M.M.
Dec 16, 2019
jmh530
Dec 16, 2019
M.M.
Dec 16, 2019
jmh530
Dec 16, 2019
jmh530
Dec 16, 2019
jmh530
Dec 16, 2019
Patrick Schluter
Dec 16, 2019
jmh530
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Patrick Schluter
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Patrick Schluter
Dec 17, 2019
Timon Gehr
[OT] Mathematical reasoning vs ad hominem and personal attacks
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Jab
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 18, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
Timon Gehr
Dec 17, 2019
jmh530
Dec 17, 2019
Timon Gehr
Dec 18, 2019
René Heldmaier
Dec 17, 2019
Timon Gehr
Dec 17, 2019
NaN
Dec 16, 2019
Guillaume Piolat
Dec 16, 2019
mipri
Dec 16, 2019
Timon Gehr
Dec 16, 2019
Timon Gehr
December 15, 2019
A few hours ago I closed issue 7006 [1] as a WONTFIX. Now timon.gehr@gmx.ch opened it again, without any explanation. As I don't wont to start an edit war, I prefere to get some other opinions from the community.

It's about the integer overload of pow() in std.math and the issue askes for adding support for negative exponents. IMHO there are two possibilites and non of them makes sense to me:

a) Result type integral: There is no usecase, because in almost all cases the result is a fraction which cannot be expressed as an integral type. Even when looking at this as a division with reminder, the value would always almost be 0. Again not very useful.

b) Result type floating: This would be a breaking change. If the user wishes this behaviour he could convert the base to a floating type first and then call pow. Additionally it occasionally would produce wrong results as I pointed out in my closing message.

What do you think about this?

[1] https://issues.dlang.org/show_bug.cgi?id=7006
December 15, 2019
On 15.12.19 19:22, berni44 wrote:
> A few hours ago I closed issue 7006 [1] as a WONTFIX. Now timon.gehr@gmx.ch opened it again, without any explanation.

You didn't provide an explanation for closing the issue, so I assumed it was an accident. -1^^-1 leading to "division by zero" instead of the correct answer of -1 makes no sense at all.

> As I don't wont to start an edit war, I prefere to get some other opinions from the community.
> 
> It's about the integer overload of pow() in std.math and the issue askes for adding support for negative exponents. IMHO there are two possibilites and non of them makes sense to me:
> 
> a) Result type integral: There is no usecase,

Nonsense, e.g., (-1)^^i.

> because in almost all cases the result is a fraction which cannot be expressed as an integral type. Even when looking at this as a division with reminder, the value would always almost be 0. Again not very useful.
> 
> b) Result type floating: This would be a breaking change. If the user wishes this behaviour he could convert the base to a floating type first and then call pow. Additionally it occasionally would produce wrong results as I pointed out in my closing message.
> ...

This is not an option.

> What do you think about this?
> 
> [1] https://issues.dlang.org/show_bug.cgi?id=7006

A negative exponent should behave like a negative exponent. I.e., a^^-1 = 1/a. There's no good reason to do anything else.
December 15, 2019
On Sunday, 15 December 2019 at 18:31:14 UTC, Timon Gehr wrote:
> You didn't provide an explanation for closing the issue, so I assumed it was an accident.

I wrote something about the floating result stuff, which was meant as an explanation. Sorry, if that wasn't clear.

> -1^^-1 leading to "division by zero" instead of the correct answer of -1 makes no sense at all.

I agree, that "division by zero" is not the best here. I guess, that the original programmer wanted to avoid throwing an exception.

>> a) Result type integral: There is no usecase,
>
> Nonsense, e.g., (-1)^^i.

Yeah, but what do you want to do with that? If the base is something other than -1, 0 or 1 the result is a fraction, which cannot be represented by an integral type. What should be the outcome of the function in that case?

>> b) Result type floating: This would be a breaking change. If the user wishes this behaviour he could convert the base to a floating type first and then call pow. Additionally it occasionally would produce wrong results as I pointed out in my closing message.
>> ...
>
> This is not an option.

OK. Here we have the same oppinion. :-)

> A negative exponent should behave like a negative exponent. I.e., a^^-1 = 1/a. There's no good reason to do anything else.

Meanwhile I think, I understand, what you want to have. That would mean, that the answer of my question above would be 0 for all fractions. Correct? I'm just not sure, if this is the best alternative...

I'll file a PR with that and we'll see, what the reviewers will say.

December 16, 2019
On Sunday, 15 December 2019 at 18:22:28 UTC, berni44 wrote:
>
> What do you think about this?
>

That to desire a result is such useless it's probably indicative of a logic error aka bug. Or the user expected a FP return type and as such it should crash and warn the user.
December 16, 2019
On Monday, 16 December 2019 at 00:51:55 UTC, Guillaume Piolat wrote:
> On Sunday, 15 December 2019 at 18:22:28 UTC, berni44 wrote:
>>
>> What do you think about this?
>>
>
> That to desire a result is such useless it's probably indicative of a logic error aka bug. Or the user expected a FP return type and as such it should crash and warn the user.

It can be "probably a logical error" for subtraction to return
a negative result. It can be "probably a logic error" for
integer division to have a remainder. Mathematical functions
should do as they're told and let the caller sort out what
meaning a calculation has.
December 16, 2019
On 16.12.19 01:51, Guillaume Piolat wrote:
> On Sunday, 15 December 2019 at 18:22:28 UTC, berni44 wrote:
>>
>> What do you think about this?
>>
> 
> That to desire a result is such useless ...
(-1)^^i is not useless.
December 16, 2019
On 15.12.19 20:52, berni44 wrote:
> On Sunday, 15 December 2019 at 18:31:14 UTC, Timon Gehr wrote:
>> You didn't provide an explanation for closing the issue, so I assumed it was an accident.
> 
> I wrote something about the floating result stuff, which was meant as an explanation. Sorry, if that wasn't clear.
> 
>> -1^^-1 leading to "division by zero" instead of the correct answer of -1 makes no sense at all.
> 
> I agree, that "division by zero" is not the best here. I guess, that the original programmer wanted to avoid throwing an exception.
> ...

What I wanted you to agree to is that computing the correct result is the correct thing to do. Division by zero and throwing an exception both make no sense here.

>>> a) Result type integral: There is no usecase,
>>
>> Nonsense, e.g., (-1)^^i.
> 
> Yeah, but what do you want to do with that?

Arithmetic. (I think it I was solving some combinatorics task involving (-1)^^i, but it has been a few years and I don't remember specifics.) I wrote a correct program and instead of getting the correct answer I got a floating point exception. I then filed a bug report.

Anyway, do I really have to argue that arithmetic is useful, or that D should compute the correct result for arithmetic expressions? The whole line of reasoning where I am somehow required to justify my point of view just makes no sense to me. E.g., what's the use of 37637663*3 evaluating to 112912989 ? You can't think of a concrete use off the top of your head? Well, then maybe that expression should cause a divide by zero error because it is obviously indicative of a bug if such a thing occurred in your program?

> If the base is something other than -1, 0 or 1 the result is a fraction, which cannot be represented by an integral type. What should be the outcome of the function in that case?
> ...

Ideally 0, but that's mostly about consistency with integer division. I hope we can all agree that there is really no justification for not computing the correct result if it actually fits into the return type.

>... I'm just not sure, if this is the best alternative...

What's in Phobos now is plain broken and that's why the bug report exists.

> 
> I'll file a PR with that and we'll see, what the reviewers will say.
> 

Thanks.
December 16, 2019
On 16.12.19 01:51, Guillaume Piolat wrote:
> it's probably indicative of a logic error aka bug. Or the user expected a FP return type and as such it should crash and warn the user.

Also, please rest assured that I wrote a perfectly fine program that expected an integer result prior to filing that bug report and all the crash did was to delay me and create painful and pointless discussions on bugzilla and on the forums.
December 16, 2019
On Monday, 16 December 2019 at 02:05:46 UTC, Timon Gehr wrote:
> Anyway, do I really have to argue that arithmetic is useful, or
> that D should compute the correct result for arithmetic
> expressions? The whole line of reasoning where I am somehow
> required to justify my point of view just makes no sense to me.

It really is the case that *someone* needs to do this, because

1. the author of the code didn't share your view;

2. several other people responding to the ticket didn't share
your view; and

3. this condition has persisted for 8 years after the bug was
reported.

But you don't need to justify it that far. Just one level back.
You expect some specific behavior of pow(), but what do you
expect of functions like pow in general? What principle does
pow() violate by having this weirdly implemented domain
restriction? Would you be satisfied if the line were changed to

  enforce(n >= 0, "only natural powers are supported");

or

  assert(n >= 0);

or

  @deprecated("use floating point pow instead")

?

BEGIN Long digression

Suppose D had a filesystem interface without fine error
handling, so that an SomethingHappenedException is all you get
from trying and failing to open a file? The proper importance
level in the ticket system for this would have to be 'shameful'
or 'disqualifying': this would mean that Phobos's file handling
was only suitable for the most trivial of applications, and
that for anything else the first thing you'd have to do is fall
back to C's or some other interface. And the condition itself
would serve as a red flag in general: don't even think about D
for system administration because clearly nobody involved with
it takes those tasks seriously, so even after you work around
this problem you'll certainly run into some other obnoxious
fault that was less obvious.

Real example of that: Lua doesn't come with a regex library.
It's too good for regex, and has some NIH pattern-matcher
that's less powerful and at least as slow as libc regex() in
practice (so, a dozen times slower than PCRE).

This is an obvious problem. Should you work around it and still
try to use Lua for system administration? No! There's a much
more dangerous problem that isn't obvious at all: the normal
'lua' binary that you'd use to run Lua scripts, on startup
it'll silently eval() the contents of a specific environment
variable. This is a 'feature', and also an instant privilege
escalation exploit for any setuid Lua script. "setuid scripts
are bad"? Sure, but languages that system administrators
actually use take some pains to make them less bad, and
sysadmins are not all top-tier. People make mistakes. Quick
fixes are applied. If people started circulating completely
safe only-to-be-run-by-root Lua scripts then one day someone
will set one of them setuid and someone else will notice and
gain root on a box because of it. So it's best just to not use
Lua for this entire class of application from the very
beginning, and the earliest hint that you should do this is
Lua's pattern-matching eccentricity.

END Long digression

I can say all that because I've worked as a sysadmin and have
written and maintained a lot of sysadmin code. I can't say much
at all about std.math. The easy path, "just do what some other
languages do", leads me to libc that doesn't have an integer
pow, or to scripting languages that eagerly return a floating
point result.

Or to https://gmplib.org/manual/Integer-Exponentiation.html

December 16, 2019
On Monday, 16 December 2019 at 03:20:32 UTC, mipri wrote:
> You expect some specific behavior of pow(), but what do you
> expect of functions like pow in general? What principle does
> pow() violate by having this weirdly implemented domain
> restriction? Would you be satisfied if the line were changed to
>
>   enforce(n >= 0, "only natural powers are supported");
>
> or
>
>   assert(n >= 0);
>
> or
>
>   @deprecated("use floating point pow instead")

In this special case, I would think changing the function signature to take only "uint" as exponent would be sufficient. If you need negative exponents using the floating point pow is more useful anyway.

Of course -1^^x is a useful function, but if you need it, I would still think using floating point makes more sense. And if its time critical and you need only integers, there are much faster solutions than using pow (e.g. odd(x)?-1:1 )
« First   ‹ Prev
1 2 3 4 5 6 7 8