3 #if !defined (__ACE_INLINE__)
4 # include "ace/Stats.inl"
5 #endif /* __ACE_INLINE__ */
7 #include "ace/OS_NS_stdio.h"
8 #include "ace/OS_NS_string.h"
10 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
13 ACE_Stats_Value::fractional_field () const
15 if (precision () == 0)
21 ACE_UINT32 field
= 10;
22 for (u_int i
= 0; i
< precision () - 1; ++i
)
32 ACE_Stats::sample (const ACE_INT32 value
)
34 if (samples_
.enqueue_tail (value
) == 0)
37 if (number_of_samples_
== 0)
39 // That's a lot of samples :-)
54 // Probably failed due to running out of memory when trying to
55 // enqueue the new value.
62 ACE_Stats::mean (ACE_Stats_Value
&m
,
63 const ACE_UINT32 scale_factor
)
65 if (number_of_samples_
> 0)
67 const ACE_UINT64 ACE_STATS_INTERNAL_OFFSET
=
68 ACE_UINT64_LITERAL (0x100000000);
70 ACE_UINT64 sum
= ACE_STATS_INTERNAL_OFFSET
;
71 ACE_Unbounded_Queue_Iterator
<ACE_INT32
> i (samples_
);
82 // sum_ was initialized with ACE_STATS_INTERNAL_OFFSET, so
83 // subtract that off here.
84 quotient (sum
- ACE_STATS_INTERNAL_OFFSET
,
85 number_of_samples_
* scale_factor
,
96 ACE_Stats::std_dev (ACE_Stats_Value
&std_dev
,
97 const ACE_UINT32 scale_factor
)
99 if (number_of_samples_
<= 1)
102 std_dev
.fractional (0);
106 const ACE_UINT32 field
= std_dev
.fractional_field ();
108 // The sample standard deviation is:
110 // sqrt (sum (sample_i - mean)^2 / (number_of_samples_ - 1))
112 ACE_UINT64 mean_scaled
;
113 // Calculate the mean, scaled, so that we don't lose its
115 ACE_Stats_Value
avg (std_dev
.precision ());
117 avg
.scaled_value (mean_scaled
);
119 // Calculate the summation term, of squared differences from the
121 ACE_UINT64 sum_of_squares
= 0;
122 ACE_Unbounded_Queue_Iterator
<ACE_INT32
> i (samples_
);
128 const ACE_UINT64 original_sum_of_squares
= sum_of_squares
;
130 // Scale up by field width so that we don't lose the
131 // precision of the mean. Carefully . . .
132 const ACE_UINT64
product (*sample
* field
);
134 ACE_UINT64 difference
;
135 // NOTE: please do not reformat this code! It //
136 // works with the Diab compiler the way it is! //
137 if (product
>= mean_scaled
) //
139 difference
= product
- mean_scaled
; //
143 difference
= mean_scaled
- product
; //
145 // NOTE: please do not reformat this code! It //
146 // works with the Diab compiler the way it is! //
148 // Square using 64-bit arithmetic.
149 sum_of_squares
+= difference
* ACE_U64_TO_U32 (difference
);
152 if (sum_of_squares
< original_sum_of_squares
)
160 // Divide the summation by (number_of_samples_ - 1), to get the
161 // variance. In addition, scale the variance down to undo the
162 // mean scaling above. Otherwise, it can get too big.
163 ACE_Stats_Value
variance (std_dev
.precision ());
164 quotient (sum_of_squares
,
165 (number_of_samples_
- 1) * field
* field
,
168 // Take the square root of the variance to get the standard
169 // deviation. First, scale up . . .
170 ACE_UINT64 scaled_variance
;
171 variance
.scaled_value (scaled_variance
);
173 // And scale up, once more, because we'll be taking the square
175 scaled_variance
*= field
;
176 ACE_Stats_Value
unscaled_standard_deviation (std_dev
.precision ());
177 square_root (scaled_variance
,
178 unscaled_standard_deviation
);
181 quotient (unscaled_standard_deviation
,
182 scale_factor
* field
,
194 number_of_samples_
= 0u;
196 max_
= -0x8000 * 0x10000;
201 ACE_Stats::print_summary (const u_int precision
,
202 const ACE_UINT32 scale_factor
,
205 ACE_TCHAR mean_string
[128];
206 ACE_TCHAR std_dev_string
[128];
207 ACE_TCHAR min_string
[128];
208 ACE_TCHAR max_string
[128];
211 for (int tmp_precision
= precision
;
212 ! overflow_
&& ! success
&& tmp_precision
>= 0;
215 // Build a format string, in case the C library doesn't support %*u.
216 ACE_TCHAR format
[32];
217 if (tmp_precision
== 0)
218 ACE_OS::snprintf (format
, 32, ACE_TEXT ("%%%d"), tmp_precision
);
220 ACE_OS::snprintf (format
, 32, ACE_TEXT ("%%d.%%0%du"), tmp_precision
);
222 ACE_Stats_Value
u (tmp_precision
);
223 ((ACE_Stats
*) this)->mean (u
, scale_factor
);
224 ACE_OS::snprintf (mean_string
, 128, format
, u
.whole (), u
.fractional ());
226 ACE_Stats_Value
sd (tmp_precision
);
227 if (((ACE_Stats
*) this)->std_dev (sd
, scale_factor
))
236 ACE_OS::snprintf (std_dev_string
, 128, format
, sd
.whole (),
239 ACE_Stats_Value
minimum (tmp_precision
), maximum (tmp_precision
);
242 const ACE_UINT64
m (min_
);
243 quotient (m
, scale_factor
, minimum
);
247 const ACE_UINT64
m (max_
);
248 quotient (m
, scale_factor
, maximum
);
250 ACE_OS::snprintf (min_string
, 128, format
,
251 minimum
.whole (), minimum
.fractional ());
252 ACE_OS::snprintf (max_string
, 128, format
,
253 maximum
.whole (), maximum
.fractional ());
258 ACE_OS::fprintf (file
, ACE_TEXT ("samples: %u (%s - %s); mean: ")
259 ACE_TEXT ("%s; std dev: %s\n"),
260 samples (), min_string
, max_string
,
261 mean_string
, std_dev_string
);
266 ACE_OS::fprintf (file
,
267 ACE_TEXT ("ACE_Stats::print_summary: OVERFLOW: %s\n"),
268 ACE_OS::strerror (overflow_
));
275 ACE_Stats::quotient (const ACE_UINT64 dividend
,
276 const ACE_UINT32 divisor
,
277 ACE_Stats_Value
"ient
)
279 // The whole part of the division comes from simple integer division.
280 quotient
.whole (static_cast<ACE_UINT32
> (divisor
== 0
281 ? 0 : dividend
/ divisor
));
283 if (quotient
.precision () > 0 || divisor
== 0)
285 const ACE_UINT32 field
= quotient
.fractional_field ();
287 // Fractional = (dividend % divisor) * 10^precision / divisor
289 // It would be nice to add round-up term:
290 // Fractional = (dividend % divisor) * 10^precision / divisor +
291 // 10^precision/2 / 10^precision
292 // = ((dividend % divisor) * 10^precision + divisor) /
294 quotient
.fractional (static_cast<ACE_UINT32
> (
295 dividend
% divisor
* field
/ divisor
));
299 // No fractional portion is requested, so don't bother
301 quotient
.fractional (0);
306 ACE_Stats::quotient (const ACE_Stats_Value
÷nd
,
307 const ACE_UINT32 divisor
,
308 ACE_Stats_Value
"ient
)
310 // The whole part of the division comes from simple integer division.
311 quotient
.whole (divisor
== 0 ? 0 : dividend
.whole () / divisor
);
313 if (quotient
.precision () > 0 || divisor
== 0)
315 const ACE_UINT32 field
= quotient
.fractional_field ();
317 // Fractional = (dividend % divisor) * 10^precision / divisor.
318 quotient
.fractional (dividend
.whole () % divisor
* field
/ divisor
+
319 dividend
.fractional () / divisor
);
323 // No fractional portion is requested, so don't bother
325 quotient
.fractional (0);
330 ACE_Stats::square_root (const ACE_UINT64 n
,
331 ACE_Stats_Value
&square_root
)
333 ACE_UINT32 floor
= 0;
334 ACE_UINT32 ceiling
= 0xFFFFFFFFu
;
338 // The maximum number of iterations is log_2 (2^64) == 64.
339 for (i
= 0; i
< 64; ++i
)
341 mid
= (ceiling
- floor
) / 2 + floor
;
343 // Can't divide the interval any further.
347 // Multiply carefully to avoid overflow.
348 ACE_UINT64 mid_squared
= mid
; mid_squared
*= mid
;
349 if (mid_squared
== n
)
351 else if (mid_squared
< n
)
358 square_root
.whole (mid
);
359 ACE_UINT64 mid_squared
= mid
; mid_squared
*= mid
;
361 if (square_root
.precision () && mid_squared
< n
)
363 // (mid * 10^precision + fractional)^2 ==
364 // n^2 * 10^(precision * 2)
366 const ACE_UINT32 field
= square_root
.fractional_field ();
372 // Do the 64-bit arithmetic carefully to avoid overflow.
373 ACE_UINT64 target
= n
;
377 ACE_UINT64 difference
= 0;
379 for (i
= 0; i
< square_root
.precision (); ++i
)
381 mid
= (ceiling
- floor
) / 2 + floor
;
383 ACE_UINT64 current
= square_root
.whole () * field
+ mid
;
384 current
*= square_root
.whole () * field
+ mid
;
388 difference
= target
- current
;
391 else if (current
<= target
)
397 // Check to see if the fractional part should be one greater.
398 ACE_UINT64 next
= square_root
.whole () * field
+ mid
+ 1;
399 next
*= square_root
.whole () * field
+ mid
+ 1;
401 square_root
.fractional (next
- target
< difference
? mid
+ 1 : mid
);
405 // No fractional portion is requested, so don't bother
407 square_root
.fractional (0);
411 ACE_END_VERSIONED_NAMESPACE_DECL