I am unable to understand when all do we need to convert numbers to bigNumbers for asserting to be equal. In some cases by mistake i missed to convert integer variables to bigNumber and they worked without error. Can somebody throw more light on the same?
There is nothing freaky about it once you get used to it. Just cast everything as BN as you go, do your math with BN and use strings when you need readable results. Keep in mind that JS is not the only system that can't deal with these high-precision numbers, e.g. databases can be a problem.
2 ^ 256 = 10 ^ 77
let value = "1234567890123456789012345678901234567890 ..." // good
... but this does not, because 2 ^ 64 is 10 ^ 20, so it's too big. That's what BN can help with.
let value = 1234567890123456789012345678901234567890 ... // fail
A BN has methods for
.mul, etc. (many!) because, again, JS cannot handle these large numbers, so convert everything to BN and perform your arithmetic with BN methods. They expect all arguments to be BN. They are lossless and always work.
You can get misleading results and things that seem to work if your testing is with low-precision numbers but you will have problems in production. This is source of confusion so I would advise against it. JS may try really hard and just truncate lower-order bits to give an answer but not necessarily the answer. Ugh. Don't rely on JS types and normal expressions for data coming and going to/from Ethereum. Consider a naming convention like
let xBN = web3.utils.toBN("1234567890123456789012345678901234567890"); let yBN = web3.utils.toBN("1"); let nextBN = xBN.add(yBN); // show me a base-10 interpretation of "next" console.log(nextBN.toString(10)); // "1234567890123456789012345678901234567891"
Of course, in practice you will get your numbers from a function, say ...
let resultBN = await myContract.getSomething(); // is BN if value is a uint256
And then you can go:
let twoBN = web3.utils.toBN("2"); let halfBN = resultBN.div(twoBN); // this is nearly lossless even if there are many digits console.log(halfBN.toString(10));
As a caveat for others who come across this. I say "nearly" lossless because division is a special case. We are dealing with integers, so rounding/truncation is unavoidable. BN has a
.mod function so you can compute the remainder and account for it.
Hope it helps.