Jump to page: 1 2
Thread overview
[Issue 9061] BigInt | BigInt, BigInt & int
Nov 07, 2013
Simen Kjaeraas
Nov 07, 2013
Simen Kjaeraas
Nov 07, 2013
Simen Kjaeraas
Nov 07, 2013
safety0ff.bugz
Nov 08, 2013
Simen Kjaeraas
Nov 08, 2013
yebblies
Nov 08, 2013
safety0ff.bugz
Nov 08, 2013
Simen Kjaeraas
Nov 08, 2013
yebblies
Nov 08, 2013
Simen Kjaeraas
Nov 23, 2013
safety0ff.bugz
Nov 24, 2013
Simen Kjaeraas
Nov 26, 2013
Simen Kjaeraas
Feb 06, 2014
safety0ff.bugz
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061


Simen Kjaeraas <simen.kjaras@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ridimz@yahoo.com


--- Comment #3 from Simen Kjaeraas <simen.kjaras@gmail.com> 2013-11-07 07:42:47 PST ---
*** Issue 10387 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061


Simen Kjaeraas <simen.kjaras@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simen.kjaras@gmail.com


--- Comment #4 from Simen Kjaeraas <simen.kjaras@gmail.com> 2013-11-07 08:10:01 PST ---
While working on this today, I noticed an unpleasant detail. What should be the result of this:

import std.bigint: BigInt;

void main() {
    BigInt a = "0xB16_B16_B16_B16_B16_B16_B16_B16_B16";
    BigInt b = 4;
    BigInt c = a & ~b; // Unset bit 3
    assert(c == BigInt("0xB16_B16_B16_B16_B16_B16_B16_B16_B12");
}

And if the comment is correct, then this is wrong:

import std.bigint : BigInt;

void main() {
    BigInt a = "0xB16_B16_B16_B16_B16_B16_B16_B16_B16";
    BigInt b = 4;
    BigInt c = a & b; // Separate bit 3
    assert(c == 4);
}

I would argue that the latter behavior is better, and a separate function may be required for the former.

Also, how should ~b work, if at all?

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #5 from bearophile_hugs@eml.cc 2013-11-07 08:30:43 PST ---
(In reply to comment #4)

> While working on this today, I noticed an unpleasant detail. What should be the result of this:
> 
> import std.bigint: BigInt;
> 
> void main() {
>     BigInt a = "0xB16_B16_B16_B16_B16_B16_B16_B16_B16";
>     BigInt b = 4;
>     BigInt c = a & ~b; // Unset bit 3
>     assert(c == BigInt("0xB16_B16_B16_B16_B16_B16_B16_B16_B12");
> }
> 
> And if the comment is correct, then this is wrong:
> 
> import std.bigint : BigInt;
> 
> void main() {
>     BigInt a = "0xB16_B16_B16_B16_B16_B16_B16_B16_B16";
>     BigInt b = 4;
>     BigInt c = a & b; // Separate bit 3
>     assert(c == 4);
> }
> 
> I would argue that the latter behavior is better, and a separate function may be required for the former.
> 
> Also, how should ~b work, if at all?

This is what Python 2.6.5 answers to your questions:

>>> a = 0xB16B16B16B16B16B16B16B16B16
>>> b = 4
>>> c = a & ~b
>>> c == 0xB16B16B16B16B16B16B16B16B12
True


>>> a = 0xB16B16B16B16B16B16B16B16B16
>>> b = 4
>>> c = a & b
>>> c
4L
>>> ~b
-5

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #6 from Simen Kjaeraas <simen.kjaras@gmail.com> 2013-11-07 10:01:14 PST ---
(In reply to comment #5)
> This is what Python 2.6.5 answers to your questions:
> 
> >>> a = 0xB16B16B16B16B16B16B16B16B16
> >>> b = 4
> >>> c = a & ~b
> >>> c == 0xB16B16B16B16B16B16B16B16B12
> True
> 
> 
> >>> a = 0xB16B16B16B16B16B16B16B16B16
> >>> b = 4
> >>> c = a & b
> >>> c
> 4L
> >>> ~b
> -5

So basically SEX[0]. That sounds nice (heh), but how do we deal with uints?

Also, std.bigint.BigInt uses signed magnitude, whereas Python uses 2's complement. Certainly it's possible to make BigInt behave the same as in Python, but I'm unsure we want to. It's certainly a data point, though.

[0]: http://en.wikipedia.org/wiki/SEX_(computing)

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061


safety0ff.bugz <safety0ff.bugz@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |safety0ff.bugz@gmail.com


--- Comment #7 from safety0ff.bugz <safety0ff.bugz@gmail.com> 2013-11-07 10:11:44 PST ---
Java / openjdk uses two's complement and GMP uses sign + magnitude but behaves as if two's complement for bitwise operations.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 07, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #8 from bearophile_hugs@eml.cc 2013-11-07 10:31:08 PST ---
Python has a library to use the very efficient GNU MP library: http://code.google.com/p/gmpy/

The results are the same (mpz is the multiprecision integer of MP):

>>> from gmpy import mpz
>>> a = mpz(0xB16B16B16B16B16B16B16B16B16)
>>> b = mpz(4)
>>> c = a & ~b
>>> c
mpz(224904433524448119807227542465298L)
>>> c == mpz(0xB16B16B16B16B16B16B16B16B12)
True

>>> a = mpz(0xB16B16B16B16B16B16B16B16B16)
>>> b = mpz(4)
>>> c = a & b
>>> c
mpz(4)
>>> ~b
mpz(-5)

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #9 from Simen Kjaeraas <simen.kjaras@gmail.com> 2013-11-08 07:46:26 PST ---
So that's all decided, then.

The remaining problem is, as stated above, uints.

As we all know, uints don't have sign bits. This means there's no sign to extend. Hence, we're back to the described problem, only slightly different.

In this case, the result should be padded with 1s:

import std.bigint : BigInt;

void main() {
    BigInt a = "0xB16_B16_B16_B16_B16_B16_B96_B16_B16";
    uint b = 0x8000_0000;
    BigInt c = a & ~b; // Unset bit 31
    assert(c == BigInt("0xB16_B16_B16_B16_B16_B16_B16_B16_B16");
}

In this case, the result should be padded with 0s:

import std.bigint : BigInt;

void main() {
    BigInt a = "0xB16_B16_B16_B16_B16_B16_B96_B16_B16";
    uint b = 0x8000_0000;
    BigInt c = a & b; // Separate bit 31
    assert(c == 0x8000_0000);
}


I'm starting to think the best solution is to simply disallow bitwise operations that involve both a uint and a BigInt, and this is what I'll implement, unless a solution is presented (that is different from 'pad with 0s', 'pad with 1s', 'pad with highest bit' and 'pad with inverse of highest bit', *and* sensible).

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #10 from yebblies <yebblies@gmail.com> 2013-11-09 02:52:35 EST ---
(In reply to comment #9)
> *and* sensible.

I'm pretty sure the answer is that it should do the same thing as converting to BigInt, then performing the bitwise operation.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #11 from safety0ff.bugz <safety0ff.bugz@gmail.com> 2013-11-08 08:03:04 PST ---
I was thinking of something more along the lines of defining ~ (complement operator) as negating the sign and subtracting one, and then when you do &,|,^, you take the two's complement on the fly.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 08, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=9061



--- Comment #12 from Simen Kjaeraas <simen.kjaras@gmail.com> 2013-11-08 08:15:51 PST ---
(In reply to comment #10)
> (In reply to comment #9)
> > *and* sensible.
> 
> I'm pretty sure the answer is that it should do the same thing as converting to BigInt, then performing the bitwise operation.

That means example one is going to break. This is not in line with the principle of least astonishment.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2