BigInteger.js icon indicating copy to clipboard operation
BigInteger.js copied to clipboard

Two's complement representation

Open r3econ opened this issue 6 years ago • 7 comments

Many times in the docs I see that the arguments passed to functions should be represented using two's complement representation. My question is how to convert a number to its two's complement representation.

What I tried is to go with:

number.not().add(1)

However this does not bring correct results. The numbers I'm working with are very large negative integers. I want to convert a large integer to to its hex signed 2's complement.

r3econ avatar Aug 21 '19 13:08 r3econ

Can you give an example of the operation that you want to do and the output that you expect?

peterolson avatar Aug 22 '19 07:08 peterolson

how about

let invert = str => str.split('').map(x => x === "0" ? "1" : "0").join('')
let myOnesComplement = bn => new BigNumber(invert(bn.toString(2)), 2)
let myTwosComplement = bn => myOnesComplement(bn).addn(1)

print(myOnesComplement(new BigNumber("-4", 10)))
// "decimal = 3, binary = 11"
print(myTwosComplement(new BigNumber("-4", 10)))
// "decimal = 4, binary = 100"

srghma avatar Feb 18 '22 18:02 srghma

@srghma but you forgot to invert infinite number of leading zeros

Yaffle avatar Feb 18 '22 22:02 Yaffle

@Yaffle could You post fixed variant, please

srghma avatar Feb 19 '22 10:02 srghma

@srghma it should look like BigInt.asUintN perhaps

Yaffle avatar Feb 19 '22 13:02 Yaffle

@Yaffle But how to invert infinite leading 0s? I thought this works by using a finite numeral with a floating (movable) sign bit, so only the sign bit must be inverted and included with the numeral (regardless if it's 0 or 1), am I missing something?

Edit: Wait I realized my mistake. "1110" <-> "0001", and "010" <-> "101", so the function treats all bits the same way, without conditionally discarding leading bits

Rudxain avatar Jun 13 '22 16:06 Rudxain

@srghma

let invert = str => str.split('').map(x => x === "0" ? "1" : "0").join('')

Can be converted to:

let inv = s => s.replace(/./gs, c => c == "0" ? "1" : "0")

But it's less readable, I guess

Rudxain avatar Jun 13 '22 16:06 Rudxain