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