Do you mean calculate more accurately the size before actually creating the table?
If so, at least some of inaccuracy may be that you would need to factor in the block size. If your row uses 4.5kb and you expect to have 1,000,000 rows you might have calculated 4.5gb but then because you can only fit one row within an 8k block (4.5 * 2 = too much) you end up using 1,000,000*8k blocks (about 8gb).
For smaller rows I'm not sure why it would be so far out...maybe incorrect calculations?
Indexes is easier to guess (fragmentation)~