Each fragment has to be tracked somewhere. That takes storage space (within the File system's plumbing, not stuff you're meant to directly access).
An example: Suppose you have a single file with 1000 fragments. Thus your file is stored through a collection of random blocks.. Rather than in a single continuous block. This means the fragmented file requires 1000x more storage space within the file system's plumbing, if only for storing addresses for each fragment. The file system plumbing keeps little dictionaries/databases/maps/tables/list to the location of each fragment of the file. So, for the file system plumbing, storing a list of a single fragment pointer doesn't need much space, compared to a list of 1000 fragment pointers..
But hey, maybe I'm wrong...
Edit: Supporting information from here:
When a non-resident data stream is too
much fragmented, so that its effective
allocation map cannot fit entirely
within the MFT record, the allocation
map may be also stored as an
non-resident stream, with just a small
resident stream containing the
indirect allocation map to the
effective non-resident allocation map
of the non-resident data stream.
Translation: If you have heavy fragmentation, the general case assumptions of the file system plumbing won't apply. As such, the FS must take steps to accommodate the fragmentation and end up costing extra storage space, just to manage the fragments. Exactly my guess from the first place.
Edit: Given the above, it still seems like 10GB being lost just to file fragmentation is crazy. I'm betting that while defragging, you had some common file system corruption that was corrected automatically. I'm thinking not only did you have massive fragmentation, but also partially deleted files taking up storage space. It would have been nice to see a scandisk log from that defrag (or a run of scandisk prior to defrag)