Like many words in crypto (e.g. wallet), the term token has several distinct definitions, mostly depending on context.
Token: usually short for ERC20 token on the Ethereum mainnet.
Token (or replaced by token name or symbol): unit used by smart contracts for accounting (smart contracts work on integers, so there can't be any decimals). Think of it as the smallest possible unit, comparable to wei for Ether.
Token (or replaced by token name or symbol): unit used for display to users (in any UI, from wallets to exchanges or any Dapp). This is comparable to Ether, which uses 18 decimals for display. When showing 1080250000000000000000 for an 18 decimals token, it is much more user-friendly to display it as 1'080.25 instead.
To maintain precision, make sure you use big integers in your JS, and convert to/from float right after/before you sanitize user input. And in your smart contract, you only reason in integers [see notes below], and that's the only kind of numbers it expects to receive as transaction data.
Be extra careful if you use less than 18 decimals, and even more so with zero. Divisions will exhibit stepwise behaviour when applied to small (or not so small, you'd be surprised) quantities of tokens and your smart contract might behave weirdly. It may even hinder the token's ability to be efficiently traded, or even listed on exchanges.
[notes] Solidity can handle fractions and high precision calculations, but when it comes to storing the result, it can only store integer values. Using the most common and optimal type, uint256
, you will be able to store numbers as large as 10**77.
If your ERC20 token uses 18 decimals, your "display token" maximum total supply is around 10**59. There is no gain in using a smaller type (e.g. uint192
) due to how the EVM works, and at 18 decimals there is already ample space in both directions (total supply, and division precision). Keep the default 18 decimals unless you really know what you are doing, why, and with which consequences.