What is words in uint256?

Let's take two variable:

uint256 public smalldata = 50000;
uint256 public data = 500 * (10**6) * 10**18;

The first on prints:

BN {
negative: 0,
words: [ 50000, <1 empty item> ],
length: 1,
red: null
}

But second one prints this:

BN {
negative: 0,
words: [ 0, 34604957, 24241406, 1654, <1 empty item> ],
length: 4,
red: null
}

What do the "words" mean? How it's calculated?

When I use data.toNumber() it gives following error:

Error: Number can only safely store up to 53 bits

But smalldata.toNumber() gives 50000.

How to print the correct value of data?

When I use data.toNumber() it gives Error: Number can only safely store up to 53 bits

That's because in Javascript, the value of Number.MAX_SAFE_INTEGER is 2 ** 53 - 1.

I mean, it would be, if 2 ** 53 was a safe integer (if you know what I mean)...

Anyway, as a general rule, avoid converting BN objects to Number.

In order to print data, you can simply use data.toString().

More generally, for any action that you want to apply on a BN object (for example, comparing it with another BN object), use the set of functions provided by the BN library, which you can find here.

Note that decimals are not supported in this library, so in order to apply a decimal operation on a BN object, you first need to convert it to a string, then to either a BigNumber object or a Decimal object, and then apply the decimal operation provided by the library that you have chosen to use.