diff --git a/printer/format/format-f.lsp b/printer/format/format-f.lsp index 55c6fd6da9071fcea8aff95d601466794c89cc46..cb8abed028715db362669d5f853f9d313a7df39b 100644 --- a/printer/format/format-f.lsp +++ b/printer/format/format-f.lsp @@ -535,8 +535,26 @@ collect (list i c f1 s1 s2)) nil) +;;; Rationale for FORMAT.F.45: CLHS 22.3.3.1 states that "d is the number of +;;; digits to print after the decimal point;" AND that the number is printed +;;; "rounded to d fractional digits". +;;; +;;; If we want to print 1.1 in a field of width 0, then we compute D to be W, +;;; minus the number of digits to be printed before the decimal point, minus 1 +;;; for the decimal point. So, in this case, D = W - 1 - 1 = 0. +;;; +;;; This means that we must print exactly 0 digits after the decimal point and +;;; that we must round the number to 0 fractional digits. The latter is doable +;;; and we round 1.1 to 1.0, BUT the first contradicts the first paragraph of +;;; 22.3.3.1 which states, "arg is printed as a float". "1." is not a float in +;;; Common Lisp, since it is read as the integer 1 in base 10. +;;; +;;; Therefore, in order to work around this corner case, we explicitly print one +;;; decimal digit so that the resulting number is recognizable as a float. Since +;;; the number was rounded to 0 decimal digits, then this digit is 0. This way, +;;; we get "1." concatenated with "0" that gives us "1.0". (def-format-test format.f.45 - "~2f" (1.1) "1.0") + "~2f ~2f" (1.1 1.9) "1.0 2.0") (def-format-test format.f.45b "~3f" (1.1) "1.1")