Thread overview
bigint
Nov 27, 2010
Ellery Newcomer
Nov 27, 2010
bearophile
Nov 27, 2010
bearophile
Nov 28, 2010
Matthias Walter
Nov 28, 2010
Kagamin
Nov 28, 2010
Don
Nov 29, 2010
Kagamin
Nov 29, 2010
Don
November 27, 2010
why does the following code fail?


import std.bigint;
void main(){
    BigInt b1 = 1;
    BigInt b2 = 3;
    BigInt e1 = 1;
    BigInt e2 = 3;
    BigInt[] b = [b1,b2];
    BigInt[] e = [e1,e2];
    assert(b == e);
}
November 27, 2010
Ellery Newcomer:

> why does the following code fail?

Reduced case for bugzilla:

import std.bigint;
void main() {
    assert([BigInt(1)] == [BigInt(1)]);
}

Bye,
bearophile
November 27, 2010
> Reduced case for bugzilla:

http://d.puremagic.com/issues/show_bug.cgi?id=5281
November 28, 2010
On 11/27/2010 02:05 PM, bearophile wrote:
>> Reduced case for bugzilla:
>> 
> http://d.puremagic.com/issues/show_bug.cgi?id=5281
> 
I investigated into the bug and the reason is the signature of opEquals, which currently is

bool opEquals(Tdummy=void)(ref const BigInt y) const
bool opEquals(T: int)(T y) const

The only working sigature for array-of-structs-comparison to work is

bool opEquals(ref const BigInt y) const

But this removes the ability to compare against ints.
(btw, it should probably be long in the 2nd signature?!)

array-comparison should definitely take templated opEquals functions into account, or is there something mentioned in the spec?

Matthias
November 28, 2010
Matthias Walter Wrote:

> bool opEquals(Tdummy=void)(ref const BigInt y) const
> bool opEquals(T: int)(T y) const
> 
> The only working sigature for array-of-structs-comparison to work is
> 
> bool opEquals(ref const BigInt y) const
> 
> But this removes the ability to compare against ints.

Why are they templated to begin with? Just for the heck of it?

bool opEquals(ref const BigInt y) const
bool opEquals(long y) const
November 28, 2010
Kagamin wrote:
> Matthias Walter Wrote:
> 
>> bool opEquals(Tdummy=void)(ref const BigInt y) const
>> bool opEquals(T: int)(T y) const
>>
>> The only working sigature for array-of-structs-comparison to work is
>>
>> bool opEquals(ref const BigInt y) const
>>
>> But this removes the ability to compare against ints.
> 
> Why are they templated to begin with? Just for the heck of it?
> 
> bool opEquals(ref const BigInt y) const
> bool opEquals(long y) const

No, because then it fails for ulong.
It's those bloody C implicit conversions.
November 29, 2010
Don Wrote:

> > Why are they templated to begin with? Just for the heck of it?
> > 
> > bool opEquals(ref const BigInt y) const
> > bool opEquals(long y) const
> 
> No, because then it fails for ulong.
> It's those bloody C implicit conversions.

hmm... works for me:
---
struct A
{
	bool opEquals(ref const A y) const
	{
		return false;
	}
	bool opEquals(long y) const
	{
		return true;
	}
}

int main()
{
	A a;
	ulong b=42;
	assert(a==b);
	return 0;
}
---
November 29, 2010
Kagamin wrote:
> Don Wrote:
> 
>>> Why are they templated to begin with? Just for the heck of it?
>>>
>>> bool opEquals(ref const BigInt y) const
>>> bool opEquals(long y) const
>> No, because then it fails for ulong.
>> It's those bloody C implicit conversions.
> 
> hmm... works for me:
> ---
> struct A
> {
> 	bool opEquals(ref const A y) const
> 	{
> 		return false;
> 	}
> 	bool opEquals(long y) const
> 	{
> 		return true;
> 	}
> }
> 
> int main()
> {
> 	A a;
> 	ulong b=42;
> 	assert(a==b);
> 	return 0;
> }
> ---
Yes, but the code is incorrect if b is larger than long.max.
The problem is that values in the range long.max+1..ulong.max
get turned into values in the range -1 .. -long.max-1

How can you distinguish them?