Coder Social home page Coder Social logo

Bitwise NOT about math HOT 21 CLOSED

brick avatar brick commented on July 21, 2024
Bitwise NOT

from math.

Comments (21)

luiz-brandao avatar luiz-brandao commented on July 21, 2024 1

Thanks for the feedback so far, I will have to take some time to analyse it with the team now. Merci.

from math.

BenMorel avatar BenMorel commented on July 21, 2024 1

it's probably up to us to manipulate it.

It probably is indeed. But it shouldn't be that hard: just add 2^(number of bits) if you get a negative result:

-8 + (2 ^ 16) = 65528

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Hi, good point, not was omitted in #16.

After a quick check, I can see that GMP does not have a gmp_not() function either. I guess the problem is that not may not make a lot of sense on an arbitrary-length integer.

Say for example you're inverting 00010101, you'll get 11101010.
But if you invert 00000000 00010101 (which is the same number as far as BigInteger is concerned), you'll get 11111111 11101010, which is a totally different number.

As such, this may not be a desirable addition to BigInteger?

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Note that Java's BigInteger does have a not() method:

https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html#not--

I'd be interested to dig into what it returns. I would suspect this performs the operation on a whole number of bytes, this number being the smallest number that fits the value.

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

I have found this implementation in another library:
https://github.com/pear/Math_BigInteger/blob/trunk/Math/BigInteger.php#L2890

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

I'm actually trying to replicate RPG's %BITNOT, so not sure it's the same as Java's. I will see if I can do some tests.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

%BITNOT seems to operate on fixed size numbers, so with no ambiguity.

Doing a NOT on an arbitrary-size integer will always lead to ambiguity: there is no unique answer.

If anything, I'd prefer to be compatible with Java's BigInteger. Hopefully this would fulfil your needs; but I'm not sure I want to go this route.

Otherwise, the solution would maybe be to create a fixed-size integer class, like FixedBigInteger, that would have a predefined length in bytes.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Any update here?

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

Hey there, good timing! We put the %BITNOT implementation on the side for now but you were right. We are having to deal with fixed length numbers in our project, since we are porting many algorithms from RPG.

For example, right now we are working on porting algorithms that work with the concept of RPG/Cobol "data structures", which are structs that can share memory space and remap those spaces to different types; evidently the size in bytes is something we have to take into account.

We are planning to apply the concept of byte streams to work around that. Fixed types, like FixedBigInteger could be an interesting tool for us and I may be able to help developing them if you feel they could be a good addition to the library.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Thanks for the feedback!

Meanwhile I checked Java's implementation, and it looks like they're doing bit arithmetic on the minimum number of bits that fit the number. The result is a negative number. I don't know if there's any use case for this, and I prefer not to venture into an implementation until someone proves to me that this use case exists.

That being said, I'd be happy with a FixedBigInteger, with an arbitrary size of $n bits, and implement bitwise operations, including NOT, there!

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Something just came up to my mind, we could also pass the number of desired bits in not:

function not(int $bits) : BigInteger

But I still consider it more or less a hack. Also, that doesn't tell us if the result should be a negative or positive number, so I guess it makes more sense to create explicit classes like FixedSignedBigInteger and FixedUnsignedBigInteger, that will leave no ambiguity as to whether the sign of the result should change!

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

Yes, I agree fixed types and explicit signed/unsigned ones make more sense.

Regarding our memory mapping problem, I have been playing with the nelexa/buffer package and the concept of buffers has been working well so far during prototyping. If we could introduce fixed types, it would allow us to get their byte representation nicely into the buffer.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

I just checked Java's BigInteger.not() implementation in more detail, and the not() operation always returns a number that fits in the same number of bytes as the original number, i.e. if the number fits in 10 bytes, the result will be the two's complement on 10 bytes.

This can be implemented as:

public function not() : BigInteger
{
    return self::fromBytes(~ $this->toBytes());
}

But this is actually equal to the negated number, minus 1. As such, the implementation can be simplified as:

public function not() : BigInteger
{
    return $this->negated()->minus(1);
}

Both of these implementations return the same results as Java's BigInteger does.
@luiz-brandao-jr could you please tell me if this implementation would be of any use for your use case?

I would be tempted to implement this not() method right now, to be consistent with Java, but I'd be curious to know if there are any real-life use cases for this one!

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Say for example you're inverting 00010101, you'll get 11101010.
But if you invert 00000000 00010101 (which is the same number as far as BigInteger is concerned), you'll get 11111111 11101010, which is a totally different number.

Actually, wrapping my head around that, I'm starting to realize my mistake. In two's complement representation, 11111111 11101010 is the same number as 11101010 (extra leading 1s are to negative numbers what leading 0s are to positive numbers).

So the number of bits on which you're working does not matter: whatever the number of bits, the bitwise NOT of a number will always be equal to (- number - 1), and Java's implementation makes perfect sense.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

Implemented as BigInteger::not() and released as 0.9.1! 🎉

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

Hi @BenMorel that's great news. I think we will definitely have a use case for this one.

We have a constraint right now where we are running PHP compiled at 32-bit, so some numeric values coming from the database could overflow an integer. Although rare, we could also potentially face the same issue with PHP 64-bit since we have some database fields that could store up to 8-byte unsigned integers. This is the reason we started using BigIntegers. And so it happens that some of the algorithms we are porting use bitwise functions!

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

@BenMorel one thing that might be an issue for us is that sometimes we use a BigInteger to represent an unsigned integer. This implementation will always return a signed value. I guess we will need to do some manipulation on our end to go around that.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

@luiz-brandao-jr How do you get your value out of the database? As a numeric string? Can you please give an example of where using a signed BigInteger is problematic?

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

@BenMorel yes, we get the value as a numeric string from the database but we can also get data from byte streams/buffers.

Example:
Let's say we get a 2-byte unsigned integer from a stream, let's say 7 (this is to make it simple, but in our case it could go up to 8-byte numbers). If we use BigInteger::of('7')->not() we get -8, but with a 2-byte unsigned it should be 65528 (11111111 11111000). But fundamentally it's because we are dealing with fixed sized values, and it's probably up to us to manipulate it.

from math.

BenMorel avatar BenMorel commented on July 21, 2024

but we can also get data from byte streams/buffers.

By the way, in the latest version you have a fromBytes() factory method that can read binary data out of a string, either signed or unsigned!

from math.

luiz-brandao avatar luiz-brandao commented on July 21, 2024

Great, I will take a look at fromBytes. Merci.

from math.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.