bignum still appears to store the value as an IV though.
No, they're objects*. See the output of perl -Mbignum -MDevel::Peek -e 'my $x=1; Dump($x)' or perl -Mbignum -MData::Dump -e 'my $x=1; dd($x)'.
It would seem that some kind of overloading solution may be the way to go, let Perl handle the storage, but overload the operations with XSUBS that do type checking/coercion. Or even straight up Inlining C.
Well, again, if you don't tell us what for, we can't really comment.
* Update: I guess you maybe mean internally? The point is, how they're stored internally is abstracted and encapsulated in an object, and you shouldn't worry about it. bignum will allow you to work with numbers of any size and any precision without any loss due to the usual floating-point imprecisions, overflows, etc.