/[eiffelstudio]/FreeELKS/tags/EiffelSoftware/Eiffel_64/library/support/format_double.e
ViewVC logotype

Contents of /FreeELKS/tags/EiffelSoftware/Eiffel_64/library/support/format_double.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 91771 - (show annotations)
Tue Jul 28 23:03:38 2009 UTC (10 years, 4 months ago) by manus_eiffel
File size: 5698 byte(s)
Fixed bug#16027 where in 6.4 we changed the default to no show trailing zeros compared to previous versions
  which is a breaking change.

1 note
2
3 description:
4 "Formatter for non-integral numbers"
5
6 library: "Free implementation of ELKS library"
7 copyright: "Copyright (c) 2005, Eiffel Software and others"
8 license: "Eiffel Forum License v2 (see forum.txt)"
9 names: format_double;
10 date: "$Date$"
11 revision: "$Revision$"
12
13 class FORMAT_DOUBLE
14
15 inherit
16 FORMAT_INTEGER
17 rename
18 make as set_defaults,
19 split as split_integral,
20 formatted as fm_formatted
21 export {NONE}
22 fm_formatted
23 redefine
24 comma_separate,
25 underscore_separate,
26 remove_separator
27 end
28
29 DOUBLE_MATH
30 export {NONE}
31 all
32 end
33
34 create
35 make
36
37 feature -- Initialization
38
39 make (w, d: INTEGER)
40 require
41 reasonable_field: w >= 1
42 reasonable_decimals: d <= w
43 do
44 set_defaults (w)
45 decimals := d
46 decimal := '.'
47 trailing_zeros_shown := True
48 ensure
49 blank_fill: fill_character = ' '
50 show_sign_negative: show_sign_negative
51 no_separator: no_separator
52 width_set: width = w
53 right_justified: right_justified
54 leading_sign: leading_sign
55 decimals_set: decimals = d
56 decimal_point: decimal = '.'
57 trailing_zeros_shown: trailing_zeros_shown
58 end
59
60 feature -- Access
61
62 after_decimal_separate: BOOLEAN
63 -- Use separators after the decimal?
64
65 decimals: INTEGER
66 -- Number of digits after the decimal point.
67
68 zero_not_shown: BOOLEAN
69 -- Show 0.5 as .5 or 0.5?
70
71 trailing_zeros_shown: BOOLEAN
72 -- Show 0.5000 as 0.5 or 0.5000?
73
74 decimal: CHARACTER
75 -- What is used for the decimal
76
77 feature -- Status setting
78
79 point_decimal
80 -- Use . as the decimal point.
81 do
82 decimal := '.'
83 ensure
84 decimal = '.'
85 end
86
87 comma_decimal
88 -- Use , as the decimal point.
89 do
90 decimal := ','
91 ensure
92 decimal = ','
93 end
94
95 set_decimals (d: INTEGER)
96 -- `d' decimals to be displayed.
97 require
98 d <= width
99 do
100 decimals := d
101 ensure
102 decimals = d
103 end
104
105 separate_after_decimal
106 -- Use separators after the decimal.
107 do
108 after_decimal_separate := True
109 ensure
110 after_decimal_separate
111 end
112
113 no_separate_after_decimal
114 -- Do not use separators after the decimal.
115 do
116 after_decimal_separate := False
117 ensure
118 not after_decimal_separate
119 end
120
121 underscore_separate
122 -- Set the separator to be underscore.
123 do
124 separator := '_'
125 separate_after_decimal
126 ensure then
127 after_decimal_separate
128 end
129
130 comma_separate
131 -- Set the separator to be comma.
132 do
133 separator := ','
134 separate_after_decimal
135 ensure then
136 after_decimal_separate
137 end
138
139 remove_separator
140 -- Remove the separator.
141 do
142 separator := '%U'
143 no_separate_after_decimal
144 ensure then
145 not after_decimal_separate
146 end
147
148 show_zero
149 -- Show 0.5 as 0.5 .
150 do
151 zero_not_shown := False
152 ensure
153 not zero_not_shown
154 end
155
156 show_trailing_zeros
157 -- Show 0.5000 as 0.5000.
158 do
159 trailing_zeros_shown := True
160 ensure
161 trailing_zeros_shown_set: not trailing_zeros_shown
162 end
163
164 hide_zero
165 -- Show 0.5 as .5 .
166 do
167 zero_not_shown := True
168 ensure
169 zero_not_shown
170 end
171
172 hide_trailing_zeros
173 -- Show 0.5000 as 0.5, and 0.0000 as 0.0.
174 do
175 trailing_zeros_shown := False
176 ensure
177 trailing_zeros_shown_set: trailing_zeros_shown
178 end
179
180 feature -- Conversion
181
182 formatted (d: DOUBLE): STRING
183 -- Format `d'.
184 local
185 sign: INTEGER
186 integral, fraction: DOUBLE
187 ints, fracs: STRING
188 value: DOUBLE
189 do
190 value := d
191 sign := 1
192
193 if d < 0 then
194 sign := -1
195 value := -value
196 end
197
198 value := value + 5 * 10 ^(- decimals - 1)
199
200 integral := floor (value)
201 fraction := floor ((value - integral) * 10 ^(decimals + 1))
202
203 if not no_separator then
204 ints := split_integral (integral.out)
205 if after_decimal_separate then
206 fracs := separate_fraction (pad_fraction (fraction))
207 else
208 fracs := pad_fraction (fraction)
209 end
210 else
211 ints := integral.out
212 fracs := pad_fraction (fraction)
213 end
214 create Result.make (width)
215 if integral /= 0 or else not zero_not_shown then
216 Result.append (ints)
217 end
218 if not Result.has ('e') then
219 Result.extend (decimal)
220 if decimals > 0 then
221 Result.append (fracs)
222 end
223 if not ignore_sign then
224 Result := process_sign (Result, sign)
225 end
226 end
227 if justification /= No_justification and then Result.count < width then
228 Result := justify (Result)
229 end
230 ensure
231 exists: Result /= Void
232 correct_length: not_justified or Result.count >= width
233 end
234
235 feature {NONE} -- Implementation
236
237 pad_fraction (f: DOUBLE): STRING
238 -- Stretch or shrink `f' to length `decimals' .
239 local
240 i: INTEGER
241 do
242 Result := f.out
243 Result.remove_tail (1)
244 if Result.count > decimals then
245 Result := Result.substring (1, decimals)
246 else
247 from
248 until
249 Result.count = decimals
250 loop
251 Result.precede ('0')
252 end
253 end
254 if not trailing_zeros_shown then
255 -- Remove all but one trailing zero from the fraction part
256 from
257 i := Result.count
258 until
259 i = 1 or else Result.item (i) /= '0'
260 loop
261 Result.remove (i)
262 i := i - 1
263 end
264 end
265 ensure
266 Result.count = decimals
267 end
268
269 separate_fraction (s: STRING): STRING
270 -- Apply separators to the fraction.
271 require
272 efficiency: separator /= '%U'
273 local
274 count, sep_length: INTEGER
275 do
276 from
277 count := 1
278 create Result.make (width)
279 until
280 count > s.count - 3
281 loop
282 from
283 sep_length := 0
284 until
285 sep_length = 3
286 loop
287 Result.extend (s.item (count))
288 count := count + 1
289 sep_length := sep_length + 1
290 end
291 Result.extend (separator)
292 end
293 from
294 until
295 count > s.count
296 loop
297 Result.extend (s.item (count))
298 count := count + 1
299 end
300 end
301
302 invariant
303 separate_all: no_separator implies not after_decimal_separate
304
305 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23