"We have a rule that's simple to explain, whose implications can be subtle to work out, but which programmers are expected to exercise taste in using. That could describe all of lisp."
I don't think the syntax for numbers is very easy to explain. That's the weak link, IMO.
If it were me, I'd have no number literals, just a tool for translating number-like symbols into numbers. Of course, that approach would make arithmetic even less readable. :)
I think the next simplest option is to treat digits as a separate partition of characters like the partitions for infix and non-infix. Digits are sufficient to represent unsigned bigints with a simple syntax. Then most of the additional features of C's float syntax could be addressed by other operators:
(neg (20.@1002 * 10^23))
This hackish .@ operator, which simulates a decimal point, could be defined in Arc as follows:
(def dot-at (a b)
(while (<= 2 b)
(zap [/ _ 10] b))
(+ a (- b 1)))
You could avoid the need for this hack by treating . as a number character, but then you lose it as an operator.