]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/perf/perldriver/Format.pm
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / perf / perldriver / Format.pm
1 #!/usr/local/bin/perl\r
2 #  ********************************************************************\r
3 #  * COPYRIGHT:\r
4 #  * Copyright (c) 2006, International Business Machines Corporation and\r
5 #  * others. All Rights Reserved.\r
6 #  ********************************************************************\r
7 \r
8 my $PLUS_MINUS = "±";\r
9 \r
10 #|#---------------------------------------------------------------------\r
11 #|# Format a confidence interval, as given by a Dataset.  Output is as\r
12 #|# as follows:\r
13 #|#   241.23 - 241.98 => 241.5 +/- 0.3\r
14 #|#   241.2 - 243.8 => 242 +/- 1\r
15 #|#   211.0 - 241.0 => 226 +/- 15 or? 230 +/- 20\r
16 #|#   220.3 - 234.3 => 227 +/- 7\r
17 #|#   220.3 - 300.3 => 260 +/- 40\r
18 #|#   220.3 - 1000 => 610 +/- 390 or? 600 +/- 400\r
19 #|#   0.022 - 0.024 => 0.023 +/- 0.001\r
20 #|#   0.022 - 0.032 => 0.027 +/- 0.005\r
21 #|#   0.022 - 1.000 => 0.5 +/- 0.5\r
22 #|# In other words, take one significant digit of the error value and\r
23 #|# display the mean to the same precision.\r
24 #|sub formatDataset {\r
25 #|    my $ds = shift;\r
26 #|    my $lower = $ds->getMean() - $ds->getError();\r
27 #|    my $upper = $ds->getMean() + $ds->getError();\r
28 #|    my $scale = 0;\r
29 #|    # Find how many initial digits are the same\r
30 #|    while ($lower < 1 ||\r
31 #|           int($lower) == int($upper)) {\r
32 #|        $lower *= 10;\r
33 #|        $upper *= 10;\r
34 #|        $scale++;\r
35 #|    }\r
36 #|    while ($lower >= 10 &&\r
37 #|           int($lower) == int($upper)) {\r
38 #|        $lower /= 10;\r
39 #|        $upper /= 10;\r
40 #|        $scale--;\r
41 #|    }\r
42 #|}\r
43 \r
44 #---------------------------------------------------------------------\r
45 # Format a number, optionally with a +/- delta, to n significant\r
46 # digits.\r
47 #\r
48 # @param significant digit, a value >= 1\r
49 # @param multiplier\r
50 # @param time in seconds to be formatted\r
51 # @optional delta in seconds\r
52 #\r
53 # @return string of the form "23" or "23 +/- 10".\r
54 #\r
55 sub formatNumber {\r
56     my $sigdig = shift;\r
57     my $mult = shift;\r
58     my $a = shift;\r
59     my $delta = shift; # may be undef\r
60     \r
61     my $result = formatSigDig($sigdig, $a*$mult);\r
62     if (defined($delta)) {\r
63         my $d = formatSigDig($sigdig, $delta*$mult);\r
64         # restrict PRECISION of delta to that of main number\r
65         if ($result =~ /\.(\d+)/) {\r
66             # TODO make this work for values with all significant\r
67             # digits to the left of the decimal, e.g., 1234000.\r
68 \r
69             # TODO the other thing wrong with this is that it\r
70             # isn't rounding the $delta properly.  Have to put\r
71             # this logic into formatSigDig().\r
72             my $x = length($1);\r
73             $d =~ s/\.(\d{$x})\d+/.$1/;\r
74         }\r
75         $result .= " $PLUS_MINUS " . $d;\r
76     }\r
77     $result;\r
78 }\r
79 \r
80 #---------------------------------------------------------------------\r
81 # Format a time, optionally with a +/- delta, to n significant\r
82 # digits.\r
83 #\r
84 # @param significant digit, a value >= 1\r
85 # @param time in seconds to be formatted\r
86 # @optional delta in seconds\r
87 #\r
88 # @return string of the form "23 ms" or "23 +/- 10 ms".\r
89 #\r
90 sub formatSeconds {\r
91     my $sigdig = shift;\r
92     my $a = shift;\r
93     my $delta = shift; # may be undef\r
94 \r
95     my @MULT = (1   , 1e3,  1e6,  1e9);\r
96     my @SUFF = ('s' , 'ms', 'us', 'ns');\r
97 \r
98     # Determine our scale\r
99     my $i = 0;\r
100     #always do seconds if the following line is commented out\r
101     ++$i while ($a*$MULT[$i] < 1 && $i < @MULT);\r
102     \r
103     formatNumber($sigdig, $MULT[$i], $a, $delta) . ' ' . $SUFF[$i];\r
104 }\r
105 \r
106 #---------------------------------------------------------------------\r
107 # Format a percentage, optionally with a +/- delta, to n significant\r
108 # digits.\r
109 #\r
110 # @param significant digit, a value >= 1\r
111 # @param value to be formatted, as a fraction, e.g. 0.5 for 50%\r
112 # @optional delta, as a fraction\r
113 #\r
114 # @return string of the form "23 %" or "23 +/- 10 %".\r
115 #\r
116 sub formatPercent {\r
117     my $sigdig = shift;\r
118     my $a = shift;\r
119     my $delta = shift; # may be undef\r
120     \r
121     formatNumber($sigdig, 100, $a, $delta) . '%';\r
122 }\r
123 \r
124 #---------------------------------------------------------------------\r
125 # Format a number to n significant digits without using exponential\r
126 # notation.\r
127 #\r
128 # @param significant digit, a value >= 1\r
129 # @param number to be formatted\r
130 #\r
131 # @return string of the form "1234" "12.34" or "0.001234".  If\r
132 #         number was negative, prefixed by '-'.\r
133 #\r
134 sub formatSigDig {\r
135     my $n = shift() - 1;\r
136     my $a = shift;\r
137 \r
138     local $_ = sprintf("%.${n}e", $a);\r
139     my $sign = (s/^-//) ? '-' : '';\r
140 \r
141     my $a_e;\r
142     my $result;\r
143     if (/^(\d)\.(\d+)e([-+]\d+)$/) {\r
144         my ($d, $dn, $e) = ($1, $2, $3);\r
145         $a_e = $e;\r
146         $d .= $dn;\r
147         $e++;\r
148         $d .= '0' while ($e > length($d));\r
149         while ($e < 1) {\r
150             $e++;\r
151             $d = '0' . $d;\r
152         }\r
153         if ($e == length($d)) {\r
154             $result = $sign . $d;\r
155         } else {\r
156             $result = $sign . substr($d, 0, $e) . '.' . substr($d, $e);\r
157         }\r
158     } else {\r
159         die "Can't parse $_";\r
160     }\r
161     $result;\r
162 }\r
163 \r
164 1;\r
165 \r
166 #eof\r