From d70e80e837087a5849a4189ff8667a3411822bbe Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 7 Sep 2012 21:28:39 -0400 Subject: [PATCH] racket/format: change ~r to accept #:notation argument Another possibility would be #:exponential? (or/c boolean? (-> rational? boolean?)) but that violates the "everything's a boolean" convention. --- collects/racket/format.rkt | 43 ++++--- collects/scribblings/reference/format.scrbl | 64 +++++---- collects/tests/racket/format.rkt | 136 ++++++++++---------- 3 files changed, 126 insertions(+), 117 deletions(-) diff --git a/collects/racket/format.rkt b/collects/racket/format.rkt index 5cfb7d1306..ba334c76eb 100644 --- a/collects/racket/format.rkt +++ b/collects/racket/format.rkt @@ -60,7 +60,8 @@ [~.s format/c] [~.v format/c] [~r (->* (rational?) - (#:exponential? any/c + (#:notation (or/c 'positional 'exponential + (-> rational? (or/c 'positional 'exponential))) #:sign sign-mode/c #:base base/c #:precision precision/c @@ -177,29 +178,29 @@ #:sign [sign-mode #f] #:base [base 10] #:precision [precision 6] - #:exponential? [exponential? (not (or (zero? N) - (< (expt (extract base) (- (extract precision))) - (abs N) - (expt (extract base) (extract precision)))))] + #:notation [notation 'positional] #:format-exponent [exp-format-exponent #f] #:min-width [pad-digits-to 1] #:pad-string [digits-padding " "]) - (if exponential? - (catne N - #:who 'catn - #:sign sign-mode - #:base base - #:precision precision - #:format-exponent exp-format-exponent - #:pad-digits-to pad-digits-to - #:digits-padding digits-padding) - (catnp N - #:who 'catn - #:sign sign-mode - #:base base - #:precision precision - #:pad-digits-to pad-digits-to - #:digits-padding digits-padding))) + (let ([notation (if (procedure? notation) (notation N) notation)]) + (case notation + ((exponential) + (catne N + #:who 'catn + #:sign sign-mode + #:base base + #:precision precision + #:format-exponent exp-format-exponent + #:pad-digits-to pad-digits-to + #:digits-padding digits-padding)) + ((positional) + (catnp N + #:who 'catn + #:sign sign-mode + #:base base + #:precision precision + #:pad-digits-to pad-digits-to + #:digits-padding digits-padding))))) (define (catnp N #:who [who 'catnp] diff --git a/collects/scribblings/reference/format.scrbl b/collects/scribblings/reference/format.scrbl index 0413160de7..b2b3341764 100644 --- a/collects/scribblings/reference/format.scrbl +++ b/collects/scribblings/reference/format.scrbl @@ -12,7 +12,6 @@ (the-eval '(require racket/math racket/format))) @title[#:tag "format"]{Converting Values to Strings} -@author[@author+email["Ryan Culpepper" "ryanc@racket-lang.org"]] @note-lib[racket/format] @@ -47,7 +46,7 @@ at most @racket[max-width] characters. (~a #\w "e" 'st) (~a (list "red" 'green #"blue")) (~a 17) -(~a #e1e20) +(eval:alts (~a @#,(racketvalfont "#e1e20")) (~a #e1e20)) (~a pi) (~a (expt 6.1 87)) ] @@ -189,17 +188,10 @@ marker is @racket["..."]. (or/c exact-nonnegative-integer? (list/c '= exact-nonnegative-integer?)) 3] - [#:exponential? exponential - any/c - (let ([num (lambda (n) (if (list? n) (cadr n) n))]) - (not (or (zero? x) - (< (expt (num base) (- (num precision))) - (abs x) - (expt (num base) (num precision))))))] - [#:exp-precision exp-precision - (or/c exact-nonnegative-integer? - (list/c '= exact-nonnegative-integer?)) - 5] + [#:notation notation + (or/c 'positional 'exponential + (-> rational? (or/c 'positional 'exponential))) + 'positional] [#:format-exponent format-exponent (or/c #f string? (-> exact-integer? string?)) #f] @@ -209,17 +201,35 @@ marker is @racket["..."]. Converts the rational number @racket[x] to a string in either positional or exponential notation, depending on -@racket[exponential?]. The exactness or inexactness of @racket[x] does -not affect its formatting. +@racket[notation]. The exactness or inexactness of @racket[x] does not +affect its formatting. The optional arguments control number formatting: @itemize[ -@item{@racket[precision] --- controls the number of digits after the decimal point -(or more accurately, the -@hyperlink["http://en.wikipedia.org/wiki/Radix_point"]{radix point}). When @racket[x] -is converted to exponential form, @racket[precision] applies only to the significand. +@item{@racket[notation] --- determines whether the number is printed +in positional or exponential notation. If @racket[notation] is a +function, it is applied to @racket[x] to get the notation to be used. + +@interaction[#:eval the-eval +(~r 12345) +(~r 12345 #:notation 'exponential) +(let ([pick-notation + (lambda (x) + (if (or (< (abs x) 0.001) (> (abs x) 1000)) + 'exponential + 'positional))]) + (for/list ([i (in-range 1 5)]) + (~r (expt 17 i) #:notation pick-notation))) +] +} + +@item{@racket[precision] --- controls the number of digits after the +decimal point (or more accurately, the +@hyperlink["http://en.wikipedia.org/wiki/Radix_point"]{radix point}). +When @racket[x] is formatted in exponential form, @racket[precision] +applies to the significand. If @racket[precision] is a natural number, then up to @racket[precision] digits are displayed, but trailing zeroes are dropped, and if all digits after the decimal @@ -240,7 +250,7 @@ decimal point are used, and the decimal point is never dropped. @item{@racket[min-width] --- if @racket[x] would normally be printed with fewer than @racket[min-width] digits (including the decimal -point but not including the sign indicator), the output is left-padded +point but not including the sign indicator), the digits are left-padded using @racket[pad-string]. @interaction[#:eval the-eval @@ -250,7 +260,8 @@ using @racket[pad-string]. (~r 1.5 #:min-width 4) (~r 1.5 #:precision 4 #:min-width 10) (~r 1.5 #:precision '(= 4) #:min-width 10) -(~r 1e10 #:min-width 6) +(eval:alts (~r @#,(racketvalfont "#e1e10") #:min-width 6) + (~r #e1e10 #:min-width 6)) ]} @item{@racket[pad-string] --- specifies the string used to pad the @@ -324,17 +335,18 @@ greater than @racket[10], then upper-case letters are used. (~r 4.5 #:base 2) (~r 3735928559 #:base 16) (~r 3735928559 #:base '(up 16)) +(~r 3735928559 #:base '(up 16) #:notation 'exponential) ]} @item{@racket[format-exponent] --- determines how the exponent is displayed. If @racket[format-exponent] is a string, the exponent is displayed with an -explicit sign (as with a @racket[sign-mode] of @racket['++]) and at least two +explicit sign (as with a @racket[sign] of @racket['++]) and at least two digits, separated from the significand by the ``exponent marker'' @racket[format-exponent]: @interaction[#:eval the-eval -(~r 1234 #:exponential? #t #:format-exponent "E") +(~r 1234 #:notation 'exponential #:format-exponent "E") ] If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is @@ -342,15 +354,15 @@ If @racket[format-exponent] is @racket[#f], the ``exponent marker'' is @racket[base] otherwise: @interaction[#:eval the-eval -(~r 1234 #:exponential? #t) -(~r 1234 #:exponential? #t #:base 8) +(~r 1234 #:notation 'exponential) +(~r 1234 #:notation 'exponential #:base 8) ] If @racket[format-exponent] is a procedure, it is applied to the exponent and the resulting string is appended to the significand: @interaction[#:eval the-eval -(~r 1234 #:exponential? #t +(~r 1234 #:notation 'exponential #:format-exponent (lambda (e) (format "E~a" e))) ]} diff --git a/collects/tests/racket/format.rkt b/collects/tests/racket/format.rkt index 4d8ba536bd..a48a1fc550 100644 --- a/collects/tests/racket/format.rkt +++ b/collects/tests/racket/format.rkt @@ -106,7 +106,7 @@ "3.141593") (tc (~r pi #:precision 4) "3.1416") -(tc (~r pi #:precision 0 #:exponential? #f) +(tc (~r pi #:precision 0) "3") (tc (~r 1.5 #:precision 4) "1.5") @@ -116,7 +116,7 @@ "50") (tc (~r 50 #:precision '(= 2)) "50.00") -(tc (~r 50 #:precision '(= 0) #:exponential? #f) +(tc (~r 50 #:precision '(= 0)) "50.") (tc (~r 17) @@ -156,119 +156,115 @@ "202") (tc (~r 4.5 #:base 2) "100.1") -(tc (~r 3735928559 #:base 16 #:precision 10) +(tc (~r 3735928559 #:base 16) "deadbeef") -(tc (~r 3735928559 #:base '(up 16) #:precision 10) +(tc (~r 3735928559 #:base '(up 16)) "DEADBEEF") (tc (~r 999 #:precision 3) "999") (tc (~r 1000 #:precision 3) - "1e+03") -(tc (~r 0.9876 #:exponential? #t #:precision 3) - "9.876e-01") + "1000") -(tc (~r 100 #:base 2 #:precision 3) - "1.101×2^+06") +;; ~r #:notation 'positional -(tc (~r 1234 #:precision 3 #:format-exponent "E") - "1.234E+03") - -(tc (~r 12345 #:precision 3) - "1.235e+04") -(tc (~r 12345 #:precision 2) - "1.23e+04") -(tc (~r 10000 #:precision 2) - "1e+04") -(tc (~r 10000 #:precision '(= 2)) - "1.00e+04") - -(tc (~r 12345 #:precision 4 - #:min-width 12) - " 1.2345e+04") - -;; ~r #:exponential? #f - -(tc (~r #:exponential? #f pi) +(tc (~r #:notation 'positional pi) "3.141593") -(tc (~r #:exponential? #f pi #:precision 4) +(tc (~r #:notation 'positional pi #:precision 4) "3.1416") -(tc (~r #:exponential? #f pi #:precision 0) +(tc (~r #:notation 'positional pi #:precision 0) "3") -(tc (~r #:exponential? #f 1.5 #:precision 4) +(tc (~r #:notation 'positional 1.5 #:precision 4) "1.5") -(tc (~r #:exponential? #f 1.5 #:precision '(= 4)) +(tc (~r #:notation 'positional 1.5 #:precision '(= 4)) "1.5000") -(tc (~r #:exponential? #f 50 #:precision 2) +(tc (~r #:notation 'positional 50 #:precision 2) "50") -(tc (~r #:exponential? #f 50 #:precision '(= 2)) +(tc (~r #:notation 'positional 50 #:precision '(= 2)) "50.00") -(tc (~r #:exponential? #f 50 #:precision '(= 0)) +(tc (~r #:notation 'positional 50 #:precision '(= 0)) "50.") -(tc (~r #:exponential? #f 17) +(tc (~r #:notation 'positional 17) "17") -(tc (~r #:exponential? #f 17 #:min-width 4) +(tc (~r #:notation 'positional 17 #:min-width 4) " 17") -(tc (~r #:exponential? #f -42 #:min-width 4) +(tc (~r #:notation 'positional -42 #:min-width 4) "- 42") -(tc (~r #:exponential? #f 1.5 #:min-width 4) +(tc (~r #:notation 'positional 1.5 #:min-width 4) " 1.5") -(tc (~r #:exponential? #f 1.5 #:precision 4 #:min-width 10) +(tc (~r #:notation 'positional 1.5 #:precision 4 #:min-width 10) " 1.5") -(tc (~r #:exponential? #f 1.5 #:precision '(= 4) #:min-width 10) +(tc (~r #:notation 'positional 1.5 #:precision '(= 4) #:min-width 10) " 1.5000") -(tc (~r #:exponential? #f -42 #:min-width 4 #:pad-string "0") +(tc (~r #:notation 'positional -42 #:min-width 4 #:pad-string "0") "-0042") -(tc (~r #:exponential? #f 17 #:min-width 4 #:pad-string "0") +(tc (~r #:notation 'positional 17 #:min-width 4 #:pad-string "0") "0017") -(tc (~r #:exponential? #f -42 #:min-width 4 #:pad-string "0") +(tc (~r #:notation 'positional -42 #:min-width 4 #:pad-string "0") "-0042") -(tc (for/list ([x '(17 0 -42)]) (~r #:exponential? #f x)) +(tc (for/list ([x '(17 0 -42)]) (~r #:notation 'positional x)) '("17" "0" "-42")) -(tc (for/list ([x '(17 0 -42)]) (~r #:exponential? #f x #:sign '+)) +(tc (for/list ([x '(17 0 -42)]) (~r #:notation 'positional x #:sign '+)) '("+17" "0" "-42")) -(tc (for/list ([x '(17 0 -42)]) (~r #:exponential? #f x #:sign '++)) +(tc (for/list ([x '(17 0 -42)]) (~r #:notation 'positional x #:sign '++)) '("+17" "+0" "-42")) -(tc (for/list ([x '(17 0 -42)]) (~r #:exponential? #f x #:sign 'parens)) +(tc (for/list ([x '(17 0 -42)]) (~r #:notation 'positional x #:sign 'parens)) '("17" "0" "(42)")) (tc (let ([sign-table '(("" " up") "an even " ("" " down"))]) - (for/list ([x '(17 0 -42)]) (~r #:exponential? #f x #:sign sign-table))) + (for/list ([x '(17 0 -42)]) (~r #:notation 'positional x #:sign sign-table))) '("17 up" "an even 0" "42 down")) -(tc (~r #:exponential? #f 100 #:base 7) +(tc (~r #:notation 'positional 100 #:base 7) "202") -(tc (~r #:exponential? #f 4.5 #:base 2) +(tc (~r #:notation 'positional 4.5 #:base 2) "100.1") -(tc (~r #:exponential? #f 3735928559 #:base 16) +(tc (~r #:notation 'positional 3735928559 #:base 16) "deadbeef") -(tc (~r #:exponential? #f 3735928559 #:base '(up 16)) +(tc (~r #:notation 'positional 3735928559 #:base '(up 16)) "DEADBEEF") -;; ~r #:exponential? #t +;; ~r #:notation 'exponential -(tc (~r #:exponential? #t 1000) - "1e+03") -(tc (~r #:exponential? #t 0.9876) - "9.876e-01") - -(tc (~r #:exponential? #t 100 #:base 2) - "1.1001×2^+06") - -(tc (~r #:exponential? #t 1234 #:format-exponent "E") - "1.234E+03") - -(tc (~r #:exponential? #t 12345 #:precision 3) +(tc (~r 12345 #:precision 3 #:notation 'exponential) "1.235e+04") -(tc (~r #:exponential? #t 12345 #:precision 2) +(tc (~r 12345 #:precision 2 #:notation 'exponential) "1.23e+04") -(tc (~r #:exponential? #t 10000 #:precision 2) +(tc (~r 10000 #:precision 2 #:notation 'exponential) "1e+04") -(tc (~r #:exponential? #t 10000 #:precision '(= 2)) +(tc (~r 10000 #:precision '(= 2) #:notation 'exponential) "1.00e+04") -(tc (~r #:exponential? #t 12345 #:min-width 12) +(tc (~r 12345 #:precision 4 #:min-width 12 #:notation 'exponential) " 1.2345e+04") + +(tc (~r #:notation 'exponential 1000) + "1e+03") +(tc (~r #:notation 'exponential 0.9876) + "9.876e-01") + +(tc (~r #:notation 'exponential 100 #:base 2) + "1.1001×2^+06") + +(tc (~r #:notation 'exponential 1234 #:format-exponent "E") + "1.234E+03") + +(tc (~r #:notation 'exponential 12345 #:precision 3) + ;; note rounding! + "1.235e+04") +(tc (~r #:notation 'exponential 12345 #:precision 2) + "1.23e+04") +(tc (~r #:notation 'exponential 10000 #:precision 2) + "1e+04") +(tc (~r #:notation 'exponential 10000 #:precision '(= 2)) + "1.00e+04") + +(tc (~r #:notation 'exponential 12345 #:min-width 12) + " 1.2345e+04") + +(tc (~r 3735928559 #:base '(up 16) #:precision 6 #:notation 'exponential) + ;; note rounding! + "D.EADBEF×16^+07")