Based on Rolando's answer, I came up with an easier method to do a staged conversion, and then compare. In the tables in question, I first added a new field of the same type. The I mirrored the values, ran the conversion, and compared the resulting values. eg, for Amount float(10,2) NOT NULL I used:
ALTER TABLE `table` ADD `AmountStaged` float(10,2) NOT NULL;
UPDATE `table` SET `AmountStaged` = `Amount`;
ALTER TABLE `table` MODIFY `AmountStaged` decimal(10,2) NOT NULL;
SELECT * FROM `table` WHERE round(`Amount`,2) <> `AmountStaged`;
Amazingly, with several tables (some upwards of 30k rows), there was only one value that did not match. Luckily, the deleted flag was set on that particular record, so it was irrelevant anyway. So upon getting the favorable results, the final step was two commands:
ALTER TABLE `table` DROP `Amount`;
ALTER TABLE `table` CHANGE `AmountStaged` `Amount` decimal(10,2) NOT NULL;
EDIT:
The zero downtime alternative would be to drop the AmountStaged column and convert the Amount column, as the conversion should be identical to the one we ran to test.
ALTER TABLE `table` MODIFY `Amount` decimal(10,2) NOT NULL;
ALTER TABLE `table` DROP `AmountStaged`;