Skip Menu |

This queue is for tickets about the Math-BigInt CPAN distribution.

Report information
The Basics
Id: 72680
Status: open
Priority: 0/
Queue: Math-BigInt

People
Owner: Nobody in particular
Requestors: user42 [...] zip.com.au
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: bigint adding boolean false
Date: Thu, 24 Nov 2011 10:59:23 +1100
To: bug-Math-BigInt [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
With recent debian Math::BigInt 1.997 and perl 5.10.1 a program use Math::BigInt; my $x = Math::BigInt->new(123); my $false = ! 1; $x += $false; print "$x\n"; prints NaN where I hoped that it would be 123. Adding a boolean false to a plain perl number works, it could be good if BigInt allowed the same.
Thank you for the report. The Math::Big(Int|Rat|Float) and big(num|int|rat) modules have different semantics than core Perl in many cases, giving unexpected results. I am working on this.
This is still returning NaN on the latest version.
On Mon Jul 09 14:48:36 2012, BBYRD wrote: Show quoted text
> This is still returning NaN on the latest version.
This has been the behaviour all the way since at least version 1.35. My worry is that changing this behaviour would break the code for those who base their code on the fact that Math::BigInt represents invalid input as NaN. I believe that changing this behaviour would require a clear warning.
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Sun, 13 Apr 2014 06:51:35 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
On Tue, April 8, 2014 10:34 am, Peter John Acklam via RT wrote: Show quoted text
> Queue: Math-BigInt > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=72680 > > > On Mon Jul 09 14:48:36 2012, BBYRD wrote:
>> This is still returning NaN on the latest version.
> > This has been the behaviour all the way since at least version 1.35. My > worry is that changing this behaviour would break the code for those who > base their code on the fact that Math::BigInt represents invalid input as > NaN. I believe that changing this behaviour would require a clear warning.
As far as I remember, the idea was that invalid inputs are be NaN (Not a number). I have missed the first part of the bug report, but why should that be changed? What is the alternative? All the best, tels -- http://bloodgate.com/galleries/
On Sun Apr 13 06:51:47 2014, nospam-abuse@bloodgate.com wrote: Show quoted text
> > As far as I remember, the idea was that invalid inputs are be NaN (Not a > number). I have missed the first part of the bug report, but why should > that be changed? What is the alternative?
The idea is good, but the downside is that the semantics are different than that of Perl itself, which comes as a surprise to many users. When Perl converts a string to a number, it parses as much as it can, and if there is anything left, it gives a warning: $ perl -wle 'print 5 + "2.3.4"' Argument "2.3.4" isn't numeric in addition (+) at -e line 1. 7.3 $ perl -wle 'print 5 + ""' Argument "" isn't numeric in addition (+) at -e line 1. 5 On the other hand, Math::Big(Int|Flaot) parses the entire string, and unless the entire string is a valid number, it returns a "NaN": $ perl -MMath::BigFloat -wle 'print Math::BigFloat -> new("5") + "2.3.4"' NaN $ perl -MMath::BigFloat -wle 'print Math::BigFloat -> new("5") + ""' NaN Several of the bug reports for the Math::Big(Int|Float) modules are related to this difference. People don't expect the semantics of Math::Big(Int|Float) to be different than that of core Perl.
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Sun, 27 Apr 2014 05:09:19 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
Dear Peter, On Sun, April 13, 2014 1:24 pm, Peter John Acklam via RT wrote: Show quoted text
> Queue: Math-BigInt > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=72680 > > > On Sun Apr 13 06:51:47 2014, nospam-abuse@bloodgate.com wrote:
>> >> As far as I remember, the idea was that invalid inputs are be NaN (Not a >> number). I have missed the first part of the bug report, but why should >> that be changed? What is the alternative?
> > The idea is good, but the downside is that the semantics are different > than that of Perl itself, which comes as a surprise to many users. > > When Perl converts a string to a number, it parses as much as it can, and > if there is anything left, it gives a warning: > > $ perl -wle 'print 5 + "2.3.4"' > Argument "2.3.4" isn't numeric in addition (+) at -e line 1. > 7.3 > > $ perl -wle 'print 5 + ""' > Argument "" isn't numeric in addition (+) at -e line 1. > 5 > > On the other hand, Math::Big(Int|Flaot) parses the entire string, and > unless the entire string is a valid number, it returns a "NaN": > > $ perl -MMath::BigFloat -wle 'print Math::BigFloat -> new("5") + "2.3.4"' > NaN > > $ perl -MMath::BigFloat -wle 'print Math::BigFloat -> new("5") + ""' > NaN > > Several of the bug reports for the Math::Big(Int|Float) modules are > related to this difference. People don't expect the semantics of > Math::Big(Int|Float) to be different than that of core Perl.
Thank you for your explanation, that makes more sense to me. Please let me expand a bit from the history of the rewrite (and my subsequent interpretion of the original code of BigInt). Please excuse the lenghty and late reply. Short version: The intention was to make Math::BigInt "correct", and not always replicate the semantics of Perl. E.g. if you pass something to it that is not interpretable as an integer or inf, it is NaN. E.g. anything that is not an integer (or float for BigFloat) SHOULD be a NaN (or inf as it may be), not silently 0. If one wants the semantics of Perl, the bignum modules are for it. Or in other words, Math::BigInt->new( something-not-an-integer ) should always result in NaN. I probably muddled the waters by treating undef as special cases, tho, because that gives the impression it should work for everything you throw at it. And clearly I never thought about !false and other wierd cases as my knowledge of Perl was more limited at that time. So some of them might work by accident. The reasons for BigInt using NaN and not 0 are manyfold, foremost consistency: Perl is quite inconsistent in some places, you can f.i. "increment" 'a', but not add 1 to to it, and neither can you add "a" to 1: te@te:$ perl -wle 'my $a = "a"; print $a++' a te@te:$ perl -wle 'my $a = "a"; print $a + 1' Argument "a" isn't numeric in addition (+) at -e line 1. 1 (There is Math::String, which attempts to get it right, but it is rarely used, I guess) Likewise differences about undef (which warns or not): te@te:$ perl -wle 'my $a = undef; print $a + 1' Use of uninitialized value $a in addition (+) at -e line 1. 1 te@te:$ perl -wle 'my $a = undef; print ++$a' 1 Replicating all these special cases would probably be a nightmare. Then there is the case of overloading: The magic of adding different things together works with overloading, but it again causes problems like that the order of the arguments influences the result: result = ClassA + ClassB operation is handled by ClassA result = ClassB + ClassA operation is handled by ClassB This means that either ClassA and ClassB need to be aware of each other (which is the model BigInt and BigFloat use, but is quite a big pain) or the result will differ, which is clearly unexpected in cases like: result = 1 + 2.5; vs. result = 2.5 + 1; Which by extension also means that BigInt needs to know about floats (and any special case that BigFloat knows about), because it needs to know when to pass (upgrade) to BigFloat. That makes it more complicated, too. And there are special cases like: for ( Math::BigInt->new(1) .. 10 ) which only work in more recent versions of Perl. Frankly, I'm still amazed that overloading actually works - but I digres :) Anyway, I've gone to great lenghts to hide BigInt under overloading (and thus make BigInt appear to work like Perl), but it doesn't always work. So my idea was to not even attempt it, and only attempt to hide all that away with "bignum", which adds a few more special cases (and is thus be slower). So, my intention was to have it work like this: Math::BigInt->new( notanumber ) => NaN -mbignum notanumber + x => NaN -mbignum specialcase + x => do what Perl does, as much as possible Now, if the consensus is that this model is rubbish, and Math::BigInt->new() should do what Perl does, and also be consistent with bignum, then well, I can't hardly argue against it. But I'd still like to point out that changing the semantics of Math::BigInt->new() might not be the best idea or even work 100%. The argumentation against changing Math::BigInt->new() in some cases is that you lose the ability to check a string against "being an integer/number" as opposed to being "interpreted as number by Perl". So at least it should be thought about what exactly the goal should be. Here are a few examples where the differences currently show: Floats: $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(1.5); print $a + 1' NaN $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(1.5); print $a + 1' NaN $ perl -wle 'my $a = 1.5; print $a + 1' 2.5 $ perl -Mbigint -wle 'my $a = 1.5; print $a + 1' 2 $ perl -Mbignum -wle 'my $a = 1.5; print $a + 1' 2.5 And these are oddly enough already consistent (minus the warnings): undef: $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(undef); print $a + 1' 1 $ perl -wle 'my $a = undef; print $a + 1' Use of uninitialized value $a in addition (+) at -e line 1. 1 $ perl -Mbigint -wle 'my $a = undef; print $a + 1' 1 $ perl -Mbignum -wle 'my $a = undef; print $a + 1' 1 NaN: $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(NaN); print $a + 1' NaN $ perl -wle 'my $a = NaN; print $a + 1' nan $ perl -Mbigint -wle 'my $a = NaN; print $a + 1' NaN $ perl -Mbignum -wle 'my $a = NaN; print $a + 1' NaN inf: $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(inf); print $a + 1' Unquoted string "inf" may clash with future reserved word at -e line 1. inf $ perl -wle 'my $a = inf; print $a + 1' Unquoted string "inf" may clash with future reserved word at -e line 1. inf $ perl -Mbigint -wle 'my $a = inf; print $a + 1' inf $ perl -Mbignum -wle 'my $a = inf; print $a + 1' inf !false: (here at least bigint and bignum are incorrect IMHO) $ perl -wle 'my $a = ! (3<5); print $a + 1' 1 $ perl -MMath::BigInt -wle 'my $a=Math::BigInt->new(!(3<5)); print $a + 1' NaN $ perl -Mbigint -wle 'my $a = Math::BigInt->new(!(3<5)); print $a + 1' NaN $ perl -Mbignum -wle 'my $a = Math::BigInt->new(!(3<5)); print $a + 1' NaN Oddly enought, true (as in (3<4) works: $ perl -wle 'print +(3<4) + 1'; 2 $ perl -MMath::BigInt -wle 'print Math::BigInt->new( (3<4) ) + 1'; 2 $ perl -Mbigint -wle 'print +(3<4) + 1'; 2 $ perl -Mbignum -wle 'print +(3<4) + 1'; 2 Here is another special case: $ perl -MMath::BigInt -wle 'my $a = "++0"; print $a + 1' Argument "++0" isn't numeric in addition (+) at -e line 1. 1 $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new("++0"); print $a + 1' NaN $ perl -Mbignum -wle 'my $a = "++0"; print $a + 1' NaN $ perl -Mbigint -wle 'my $a = "++0"; print $a + 1' NaN Again, bigint and bignum should probably handle this case as Perl does (minus the warning as usual). (It might be an idea to add the ability to emit all these warnings, but that is sep. from the discussion about the actual result.) Another case would be dual-vars: $ perl -wle 'open (my $i, "<", "foo"); print $! + 1'; 3 $ perl -Mbigint -wle 'open (my $i, "<", "foo"); print $! + 1'; NaN $ perl -Mbignum -wle 'open (my $i, "<", "foo"); print $! + 1'; NaN $ perl -MMath::BigInt -wle 'open (my $i, "<", "foo"); print Math::BigInt->new($!) + 1'; NaN bigint and bignum should print 3, too. But I'm not sure about BigInt. Both cases could be argued for, afterall, $! is both a string and a number at the same time. I'd lean towards 3 for BigInt, tho. Please let me know what you think of that. Best regards, Tels -- http://bloodgate.com/galleries/
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Mon, 28 Apr 2014 07:13:13 +1000
To: bug-Math-BigInt [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"nospam-abuse@bloodgate.com via RT" <bug-Math-BigInt@rt.cpan.org> writes: Show quoted text
> > Oddly enought, true (as in (3<4) works: > > $ perl -wle 'print +(3<4) + 1'; > 2 > $ perl -MMath::BigInt -wle 'print Math::BigInt->new( (3<4) ) + 1'; > 2 > $ perl -Mbigint -wle 'print +(3<4) + 1'; > 2 > $ perl -Mbignum -wle 'print +(3<4) + 1'; > 2
My original report concerned boolean false, which adapting this bit shows up as different perl -wle 'print +(3>4) + 1'; perl -MMath::BigInt -wle 'print Math::BigInt->new( (3>4) ) + 1'; perl -Mbigint -wle 'print +(3>4) + 1'; perl -Mbignum -wle 'print +(3>4) + 1'; => 1 NaN NaN NaN I thought perhaps each might print "1", ie. that BigInt+false would be the given BigInt unchanged. Arithmetic with booleans is fairly reasonable. Perhaps it would mean BigInt taking an empty string "" to mean zero.
In my opinion, it is not relevant to bring the increment and decrement operator into this discussions. Incrementation and addition are two different operators, so it should be no surprise that they behave differently. Claiming that this difference is inconsistent is misleading, I think. As for changing the semantics of Math::BigInt->new(), I'm not going to insist on doing this change. I just though it was a good idea to make Math::BigInt behave the way people expect. Anywa, there are other problems with Math::Big(Int|Float|Rat) that are more important.
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Fri, 2 May 2014 05:09:48 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
Daer Kevin, On Sun, April 27, 2014 5:14 pm, Kevin Ryde via RT wrote: Show quoted text
> Queue: Math-BigInt > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=72680 > > > "nospam-abuse@bloodgate.com via RT" <bug-Math-BigInt@rt.cpan.org> writes:
>> >> Oddly enought, true (as in (3<4) works: >> >> $ perl -wle 'print +(3<4) + 1'; >> 2 >> $ perl -MMath::BigInt -wle 'print Math::BigInt->new( (3<4) ) + 1'; >> 2 >> $ perl -Mbigint -wle 'print +(3<4) + 1'; >> 2 >> $ perl -Mbignum -wle 'print +(3<4) + 1'; >> 2
> > My original report concerned boolean false, which adapting this bit > shows up as different > > perl -wle 'print +(3>4) + 1'; > perl -MMath::BigInt -wle 'print Math::BigInt->new( (3>4) ) + 1'; > perl -Mbigint -wle 'print +(3>4) + 1'; > perl -Mbignum -wle 'print +(3>4) + 1'; > => > 1 > NaN > NaN > NaN > > I thought perhaps each might print "1", ie. that BigInt+false would be > the given BigInt unchanged. > > Arithmetic with booleans is fairly reasonable. Perhaps it would mean > BigInt taking an empty string "" to mean zero.
I'm trying to clarify this again, please bear with me (as I'm still trying to order my thoughts): BigInt->new() does two things: * it checks that the input is a correct integer (and what a "correct" integer is or looks like is the debate here, I think) * it creates a new BigInt object Likewise, BigInt does two things at the same time: * it implements "correct" integer math * AND it provides overloading operators for overloading magic It is of course sensible that the overloading magic does emulate what Perl does, esp. as "bigint", "bignum" etc. use that overloading magic directly to make the differences vanish. However, care should be take to not modify the part of "do correct integer math". IMHO correct is f.i. that if you add x to NaN, you get NaN, not x. And in light of this, if I get you correctly, you propose that false is treated as 0 when passed to ->new(). The point I was trying to make is that fixing/changing the overload math would necessarily result in a change to new() - and that might not be the best way or desirable. OTOH, I can't think of a good way to change the overload semantics w/o changing new(). Anyway, here is a (probably incomplete) list of things that BigInt/BigFloat might (or might not) treat as numeric/integer: * undef => 0 (this already works AFAIK) * false => 0 * true => 1 (this already works AFAIK) * dual-var => whatever the integer portion says * "NaN" => NaN * "inf" => inf So, false => 0 sounds sensible given the list above. Unfortunately, there are quite a few more things that Perl treats as numeric, f.i. "000a" => 0 and changing new() to accept this would break things that use new() to check for valid integers. And then there is the curios reverse situation in that BigInt accepts the string "000_001" as 1, while Perl does not: $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' 2 $ perl -wle 'print "000_001" + 1' Argument "000_001" isn't numeric in addition (+) at -e line 1. 1 $ perl -wle 'print 000_001 + 1' 2 Resolving all this might be a bit messy. But perhaps starting with !(3<5) would be a first step. Best regards, Tels -- http://bloodgate.com/galleries/
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Fri, 2 May 2014 05:23:15 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
Dear Peter, On Mon, April 28, 2014 4:56 am, Peter John Acklam via RT wrote: Show quoted text
> Queue: Math-BigInt > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=72680 > > > In my opinion, it is not relevant to bring the increment and decrement > operator into this discussions. Incrementation and addition are two > different operators, so it should be no surprise that they behave > differently. Claiming that this difference is inconsistent is misleading, > I think.
It was just the first example I could think of. However, both inc and dec operators use new() to construct their arguments and if the difference is how new() treats its argument, then the operators cannot be properly emulated as "being different" because both would get the same argument and had no way to differentiate between the two cases. $a = !(3<5) ++; $a = !(3<5) --; $a = !(3<5) + 1; will be all something like: Math::BigInt->new( !(3<5) )->binc(); Math::BigInt->new( !(3<5) )->badd(); Math::BigInt->new( !(3<5) )->badd( Math::BigInt->new(1) ); A different example would be perhaps: $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' 2 $ perl -wle 'print "000_001" + 1' Argument "000_001" isn't numeric in addition (+) at -e line 1. 1 $ perl -wle 'print 000_001 + 1' 2 Here emulating Perl seems an impossible change. Show quoted text
> As for changing the semantics of Math::BigInt->new(), I'm not going to > insist on doing this change. I just though it was a good idea to make > Math::BigInt behave the way people expect.
Just in case it wasn't clear, I wasn't strictly against the change, just trying to advocate to take care not to change new() too much so that it no longer rejects invalid integer inputs. Given that Math::BigInt->new( !!(3<5) ) works, I think that Math::BigInt->new( !(3<5) ) should work, too. This here doesn't seem right as it is inconsistent: $ perl -Mbignum -wle 'my $a = !!(3<5); print +($a + 1) / 3' 0.6666666666666666666666666666666666666667 $ perl -Mbignum -wle 'my $a = !(3<5); print +($a + 1) / 3' NaN Show quoted text
>Anywa, there are other problems with Math::Big(Int|Float|Rat) that are
more important. I'd like again to apologise for leaving this mess behind. If there is anything I can do to help, please point me in the right direction. best regards, tels -- http://bloodgate.com/galleries/
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Mon, 05 May 2014 08:38:25 +1000
To: bug-Math-BigInt [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"nospam-abuse@bloodgate.com via RT" <bug-Math-BigInt@rt.cpan.org> writes: Show quoted text
> > * undef => 0 (this already works AFAIK)
Maybe, though some of the undef handling in plain scalars seem like a sort of "auto-vivify" if I remember rightly. Show quoted text
> * false => 0
Yes, that was my only original posting. Show quoted text
> * dual-var => whatever the integer portion says
You'd be slightly tempted to take the string part since the integer or nv part may be a value truncated from a long string of digits. Of course in practice the string part is often text instead of number.
Hello again, Tels Show quoted text
> $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' > 2 > $ perl -wle 'print "000_001" + 1' > Argument "000_001" isn't numeric in addition (+) at -e line 1. > 1 > $ perl -wle 'print 000_001 + 1' > 2 > > Here emulating Perl seems an impossible change.
I'm not sure what you mean by "impossible change". Technically, it is not a problem to alter the behaviour so it becomes like this: $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' Argument "000_001" isn't numeric at -e line 1. 1 But is it a good idea? I'm not sure. Perhaps numbers (strings, to be more precise) that are valid numbers, except for underscores, should be treated just like today. Show quoted text
> Just in case it wasn't clear, I wasn't strictly against the change, just > trying to advocate to take care not to change new() too much so that it no > longer rejects invalid integer inputs.
I'm afraid I don't see why Math::BigInt should reject invalid input when core Perl doesn't. The change I have proposed will accept "invalid" input like undef, "", "2.3.4.5", but in all cases a warning will be issued, just like core Perl does when these values are used in a numerical context. Perhaps I should make the change and distribute it as perl-2.000-TRIAL1.tar.gz or something like that, so people can play with it and say what they think.
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Thu, 8 May 2014 15:48:09 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
Dear Peter, On Tue, May 6, 2014 3:58 am, Peter John Acklam via RT wrote: Show quoted text
> Queue: Math-BigInt > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=72680 > > > Hello again, Tels >
>> $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' >> 2 >> $ perl -wle 'print "000_001" + 1' >> Argument "000_001" isn't numeric in addition (+) at -e line 1. >> 1 >> $ perl -wle 'print 000_001 + 1' >> 2 >> >> Here emulating Perl seems an impossible change.
> > I'm not sure what you mean by "impossible change". Technically, it is not > a problem to alter the behaviour so it becomes like this: > > $ perl -MMath::BigInt -wle 'print Math::BigInt->new("000_001") + 1' > Argument "000_001" isn't numeric at -e line 1. > 1
But it would be incorrect, "000_0001" is a valid integer as BigInt does not (and should not IMO) make a distinction between "string" and "integer" form input (dual-vars a border-case, because one has to decide for one of them). And it would create inconsistencies. Why should "2" be not different from 2, but "000_0001" be treated different from 000_0001. (Actually, I think that Perl itself makes that distinction is odd - shouldn't it treat both the same way? But I digres.) As for the "it might be impossible", I was refering to the fact that it might be hard to decide if the input is a string, or a number, without somehow peeking at the internals. (You probably know better than me if it is technical possible at all). The "peaking at the internals" would also be the line of reasoning against the change, if it looks like an int, it behaves like an int. If it is a int-in-string-form, we still take it as int. Show quoted text
> But is it a good idea? I'm not sure. Perhaps numbers (strings, to be more > precise) that are valid numbers, except for underscores, should be treated > just like today.
Sorry if I don't understand this fully, but do you say that "2" should be 2, but "000_002" should not be 2? Or that it should stay like it is at the moment? Changing it: I'm pretty sure that would break code that gets numbers from text (like files) and uses BigInt to parse them. I'm not sure that such code exists, but that seems quite a drastic change to me. And making backwards-incompatible changes like that seemed always a no-no in core Perl to me. Show quoted text
>> Just in case it wasn't clear, I wasn't strictly against the change, just >> trying to advocate to take care not to change new() too much so that it >> no >> longer rejects invalid integer inputs.
> > I'm afraid I don't see why Math::BigInt should reject invalid input when > core Perl doesn't. The change I have proposed will accept "invalid" input > like undef, "", "2.3.4.5", but in all cases a warning will be issued, just > like core Perl does when these values are used in a numerical context.
Because you lose the correctness-test like: if (Math::BigInt->new('abc')->is_nan()) { ... } 'abc' is not a number, so it absolutely should result in NaN, not "0 plus a warning". Likewise for things like "2.3.4.5". That isn't valid number input. Another reason would be because BigInt does not try to emulate the behavior of Perl - instead it implements big integer math the correct way, which is a slightly different goal. "bigint" OTOH does emulate Perl more closely (it should be as transparentas possible). It is probably very easy to expect BigInt to behave exactly like Perl. (I'm not saying that making the mistake is bad, I'm trying to say that the expectation is wrong IMO). And afterall, there will always be differences between BigInt and Perl (like the accuracy). So I'm a bit undecided if it is really necessary to bring BigInt closer to Perl for invalid inputs. As for the actual bug report, I'm leaning towards treating "false" as 0, because it is actually more like a number, and less like "Invalid input". But the lines are certainly blurred on the entire subject. Hope this explains my POV a bit more. Best regards, Tels -- http://bloodgate.com/galleries/
Subject: Re: [rt.cpan.org #72680] bigint adding boolean false
Date: Thu, 8 May 2014 17:11:44 -0400
To: bug-Math-BigInt [...] rt.cpan.org
From: "Tels" <nospam-abuse [...] bloodgate.com>
Dear Peter, here is one more example which shows the inconsistencies that the Perl treatment of "numbers" vs. strings sometimes creates, and how bigint emulates it, and BigInt does not, but instead does the consistent (and from the point of mathematics "right") thing: And in my opionion that inconsistency is wrong, but can't be changed for historical reasons. But if I'd design mathematical operators I'd make it more consistent and that is why BigInt does not emulate all of Perl's little things. Some other languages (like Javascript) have the same problem, because they consider "+" to be addition and string concatenation, and while it sounds neat that you can "add" strings together, it creates all suprising problems (read bugs in software) in the real world, like "1" + 1 suddenly being "11" and not 2, depending on where the first variable came from. Back to Perl: Depending on input (string/integer) and operator (++ vs. +): $ perl -wle 'my $a = 000_001; $a++; print $a + 1;' 3 $ perl -wle 'my $a = 000001; $a++; print $a + 1;' 3 $ perl -wle 'my $a = "000001"; $a++; print $a + 1;' 3 $ perl -wle 'my $a = "000_001"; $a++; print $a + 1;' 2 bigint emulates this: $ perl -Mbigint -wle 'my $a = 000_001; $a++; print $a + 1;' 3 $ perl -Mbigint -wle 'my $a = 000001; $a++; print $a + 1;' 3 $ perl -Mbigint -wle 'my $a = "000001"; $a++; print $a + 1;' 3 $ perl -Mbigint -wle 'my $a = "000_001"; $a++; print $a + 1;' 2 BigInt does not and this is by design: $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(000_001); $a++; print $a + 1;' 3 $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new(000001); $a++; print $a + 1;' 3 $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new("000001"); $a++; print $a + 1;' 3 $ perl -MMath::BigInt -wle 'my $a = Math::BigInt->new("000_001"); $a++; print $a + 1;' 3 So please be careful to change such assumptions about what BigInt consideres valid. @Kevin: Sorry for hijacking your bugreport. Best regards, tels