As noted in other answers, rounding to an arbitrary number of decimal digits is closely related to float printing. Since the algorithms that correctly round are quite complex, the easiest way to do this correctly is to use printf.
Please note that you do not need to provide an arbitrary number of digits, an alternative is to use the shortest decimal place, which will be changed without changes in base 2. Such algorithms are used to print float in Scheme, Java, Python, Squeak / Pharo, etc. Unfortunately, neither libm printf nor any of the standard C libraries are compatible.
The scheme is even better because it prints *, where the numbers are not significant when you impose a fixed number of numbers (* means that any number will lead to the same float when converting back to base 2).
In this release http://code.google.com/p/pharo/issues/detail?id=4957 there is an attachment named Float-asMinimalDecimalFraction.st containing an implementation in Smalltalk of a similar printing algorithm than Scheme but it displays a fraction (relation two arbitrary integers), not an ASCII string.
So, for example, despite the fact that 14.2f is represented internally exactly as 14.19999980926513671875, it is not too late, you can get that the shortest decimal fraction that rounds it correctly is (142/10).
Using such code in Smalltalk, solving your problem will be trivial:
nanos := (floatingPointSeconds asMinimalDecimalFraction * 1e9) rounded.
But the code above uses exact arithmetic ( 1e9 is an integer) and arbitrary lengths of integers under the hood.
Note that doing multiplication in a float would be bad:
nanos := (aFloat * 1e9) asMinimalDecimalFraction rounded.
Indeed, although the 1e9 asFloat conversion is accurate, its value spans 21 bits, so floating point multiplication most likely accumulates rounding errors and worsens the problem of getting a short fraction.
Although I somehow technically answered the question, I would personally consider the above algorithm as pragmatically inappropriate for these reasons:
doing this with low-level C / C ++ instructions without the help of an arbitrary precision arithmetic library is not the fastest way to the result
it is very limited since it will not be applied to the results of calculations with several rounding errors (they statistically require many digits)
this is unnecessary if you can just avoid using float at all and work with nanos int
However, it is always nice to know that it exists ...