98
98
99
99
function generate_format_string (;
100
100
width= nothing ,
101
- precision= nothing ,
101
+ precision= - 1 ,
102
102
leftjustified= false ,
103
103
zeropadding= false ,
104
104
commas= false ,
@@ -131,32 +131,35 @@ function generate_format_string(;
131
131
s *= string ( width )
132
132
end
133
133
end
134
- if precision != nothing
134
+ if precision != - 1
135
135
s *= " ." * string ( precision )
136
136
end
137
137
s * conversion
138
138
end
139
139
140
140
function format {T<:Real} ( x:: T ;
141
141
width= nothing ,
142
- precision= nothing ,
142
+ precision= - 1 ,
143
143
leftjustified:: Bool = false ,
144
144
zeropadding:: Bool = false , # when right-justified, use 0 instead of space to fill
145
145
commas:: Bool = false ,
146
- signed:: Bool = false ,
146
+ signed:: Bool = false , # +/- prefix
147
147
positivespace:: Bool = false ,
148
- stripzeros:: Bool = (precision== nothing ),
148
+ stripzeros:: Bool = (precision== - 1 ),
149
149
parens:: Bool = false , # use (1.00) instead of -1.00. Used in finance
150
150
alternative:: Bool = false , # usually for hex
151
151
mixedfraction:: Bool = false ,
152
152
mixedfractionsep= " _" ,
153
153
fractionsep= " /" , # num / den
154
154
fractionwidth:: Int = 0 ,
155
155
tryden = 0 , # if 2 or higher, try to use this denominator, without losing precision
156
- conversion:: ASCIIString = " " )
156
+ suffix= " " , # useful for units/%
157
+ autoscale= :none , # :metric, :binary or :finance
158
+ conversion:: ASCIIString = " "
159
+ )
157
160
checkwidth = commas
158
161
if conversion == " "
159
- if T <: FloatingPoint || T <: Rational && precision != nothing
162
+ if T <: FloatingPoint || T <: Rational && precision != - 1
160
163
actualconv = " f"
161
164
elseif T <: Unsigned
162
165
actualconv = " x"
@@ -175,6 +178,68 @@ function format{T<:Real}( x::T;
175
178
if T <: Rational && conversion == " s"
176
179
stripzeros = false
177
180
end
181
+ if ( T <: FloatingPoint && actualconv == " f" || T <: Integer ) && autoscale != :none
182
+ actualconv = " f"
183
+ if autoscale == :metric
184
+ scales = [
185
+ (1e24 , " Y" ),
186
+ (1e21 , " Z" ),
187
+ (1e18 , " E" ),
188
+ (1e15 , " P" ),
189
+ (1e12 , " T" ),
190
+ (1e9 , " G" ),
191
+ (1e6 , " M" ),
192
+ (1e3 , " k" ) ]
193
+ if abs (x) > 1
194
+ for (mag, sym) in scales
195
+ if abs (x) >= mag
196
+ x /= mag
197
+ suffix = sym * suffix
198
+ break
199
+ end
200
+ end
201
+ elseif T <: FloatingPoint
202
+ smallscales = [
203
+ ( 1e-12 , " p" ),
204
+ ( 1e-9 , " n" ),
205
+ ( 1e-6 , " μ" ),
206
+ ( 1e-3 , " m" ) ]
207
+ for (mag,sym) in smallscales
208
+ if abs (x) < mag* 10
209
+ x /= mag
210
+ suffix = sym * suffix
211
+ break
212
+ end
213
+ end
214
+ end
215
+ else
216
+ if autoscale == :binary
217
+ scales = [
218
+ (1024.0 ^ 8 , " Yi" ),
219
+ (1024.0 ^ 7 , " Zi" ),
220
+ (1024.0 ^ 6 , " Ei" ),
221
+ (1024 ^ 5 , " Pi" ),
222
+ (1024 ^ 4 , " Ti" ),
223
+ (1024 ^ 3 , " Gi" ),
224
+ (1024 ^ 2 , " Mi" ),
225
+ (1024 , " Ki" )
226
+ ]
227
+ else # :finance
228
+ scales = [
229
+ (1e12 , " t" ),
230
+ (1e9 , " b" ),
231
+ (1e6 , " m" ),
232
+ (1e3 , " k" ) ]
233
+ end
234
+ for (mag, sym) in scales
235
+ if abs (x) >= mag
236
+ x /= mag
237
+ suffix = sym * suffix
238
+ break
239
+ end
240
+ end
241
+ end
242
+ end
178
243
179
244
nonneg = x >= 0
180
245
fractional = 0
@@ -264,6 +329,8 @@ function format{T<:Real}( x::T;
264
329
end
265
330
end
266
331
332
+ s *= suffix
333
+
267
334
if parens && ! in ( actualconv[1 ], " xX" )
268
335
# if zero or positive, we still need 1 white space on the right
269
336
if nonneg
0 commit comments