Improvements to std.math floor() / ceil()

Some changes are going on here:

1. Uses union instead to ensure that compiler doesn't emit any library calls here (seen a small speed up in benchmarking code).
2. Add float/double overloads, improvements might be negligible because isNaN and isInfinity checks perform (heavy?) conversions to long double.

This duplicates some code, so maybe we can instead template up the shared base.
whilst => while