Rev 5950 | Rev 7037 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5950 | Rev 6738 | ||
---|---|---|---|
Line 5... | Line 5... | ||
5 | * This is all amateur scriblings... So no copyrights. * |
5 | * This is all amateur scriblings... So no copyrights. * |
6 | * This source code file, and compiled objects derived from it, * |
6 | * This source code file, and compiled objects derived from it, * |
7 | * can be used and distributed without restriction, including for commercial use * |
7 | * can be used and distributed without restriction, including for commercial use * |
8 | * No warrenty whatsoever * |
8 | * No warrenty whatsoever * |
9 | ********************************************************************************* |
9 | ********************************************************************************* |
- | 10 | 20/6/2012 |
|
- | 11 | Corrected significance flaw when using prefixes |
|
- | 12 | Simplified routines |
|
- | 13 | Added type = 5 : prefix-notation with words (nano,mega,giga...etc) |
|
10 | 14 | ||
11 | 12/11/2012 |
15 | 12/11/2012 |
12 | Added support for numbers like 12345*10^12 |
16 | Added support for numbers like 12345*10^12 |
13 | 12345*10^12 --> 12345E12 ---> 1.2345*10^16 |
17 | 12345*10^12 --> 12345E12 ---> 1.2345*10^16 |
14 | 18 | ||
Line 45... | Line 49... | ||
45 | 15 peta P |
49 | 15 peta P |
46 | 12 tera T |
50 | 12 tera T |
47 | 9 giga G |
51 | 9 giga G |
48 | 6 mega M |
52 | 6 mega M |
49 | 3 kilo k |
53 | 3 kilo k |
- | 54 | ||
50 | 2 hecto h |
55 | 2 hecto h |
51 | 1 deca da |
56 | 1 deca da |
52 | -1 deci d |
57 | -1 deci d |
53 | -2 centi c |
58 | -2 centi c |
- | 59 | ||
54 | -3 milli m |
60 | -3 milli m |
55 | -6 micro µ |
61 | -6 micro µ |
56 | -9 nano n |
62 | -9 nano n |
57 | -12 pico p |
63 | -12 pico p |
58 | -15 femto f |
64 | -15 femto f |
Line 65... | Line 71... | ||
65 | #include <stdio.h> |
71 | #include <stdio.h> |
66 | #include <math.h> |
72 | #include <math.h> |
67 | #include <string.h> |
73 | #include <string.h> |
68 | #include <stdlib.h> |
74 | #include <stdlib.h> |
69 | #define MICRO "µ" |
75 | #define MICRO "µ" |
70 | #define PREFIX_START (-24) |
- | |
71 | #define PREFIX_END 24 |
- | |
72 | #define MAX_CONV 256 |
76 | #define MAX_CONV 256 |
73 | #define MAX_STRING 32 |
77 | #define MAX_STRING 32 |
- | 78 | #define PREFIX_START -24 |
|
- | 79 | #define PREFIX_END 24 |
|
74 | 80 | ||
75 | char *str_replace ( const char *word, const char *sub_word, const char *rep_word ){ |
81 | char *str_replace ( const char *word, const char *sub_word, const char *rep_word ){ |
76 | if(strlen(word) > MAX_STRING){return NULL;} |
82 | if(strlen(word) > MAX_STRING){return NULL;} |
77 | char *part_word = NULL; |
83 | char *part_word = NULL; |
78 | char *new_word = NULL; |
84 | char *new_word = NULL; |
Line 99... | Line 105... | ||
99 | } |
105 | } |
100 | return new_word; |
106 | return new_word; |
101 | } |
107 | } |
102 | 108 | ||
103 | char *printscience(double value, int sig, int format , int cnt ,int size){ |
109 | char *printscience(double value, int sig, int format , int cnt ,int size){ |
- | 110 | static char *min[] = {"","m",MICRO,"n","p","f","a","z","y"}; |
|
104 | static char * |
111 | static char *plus[] = {"","k", "M", "G", "T", "P", "E", "Z", "Y" }; |
- | 112 | static char *min_word[] = {"","milli","micro","nano","pico","femto","atto","zepto","yocto"}; |
|
105 |
|
113 | static char *plus_word[] = {"","kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta" }; |
106 | char *sign = NULL; |
114 | char *sign = NULL;char *prefix = NULL; |
107 | int exponent10; |
115 | int exponent10 = 0; |
- | 116 | int use_word = 0;if(format == 5){format = 3; use_word = 1;} /* switch to using words in stead of prefix */ |
|
- | 117 | if(value < 0.0) {sign = "-";value = -value;sig--;} else {sign = "";} if( sig == -1 ){ |
|
108 |
|
118 | /* |
109 |
|
119 | no significance truncations...just science notation 1234 -> 1.234*10^3 |
- | 120 | try (!) to use same amount of digits |
|
- | 121 | */ |
|
110 | sig = size; |
122 | sig = size; |
111 | if(format == 3){format = 1;} /* |
123 | if(format == 3){format = 1;} /* never prefix --> html notation */ |
112 | if(value < 0.0) {sign = "-";value = -value;sig--;} else {sign = "";} |
- | |
113 | exponent10=0; |
- | |
114 | if(value>=1){ |
- | |
115 | while(value > 10){ |
- | |
116 | value=value / 10.0; |
- | |
117 | exponent10++; |
- | |
118 | /* need to set a limit to number of while loops ! */ |
- | |
119 | if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;} |
- | |
120 | } |
- | |
121 | } |
- | |
122 | else /* 0 < value < 1 --> exponent10 < 0 */ |
- | |
123 | { |
- | |
124 | while(value < 1){ |
- | |
125 | value=value*10; |
- | |
126 | exponent10--; |
- | |
127 | /* need to set a limit to number of while loops ! */ |
- | |
128 | if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;} |
- | |
129 | } |
- | |
130 | } |
- | |
131 | } |
124 | } |
132 | else |
- | |
133 | { |
- | |
134 | if(value < 0.0) {sign = "-";value = -value;} else {sign = "";} |
- | |
135 |
|
125 | if(value == 0){fprintf(stdout, "%s%.*f", sign, sig-1, value);return NULL;} /* no need to go further */ |
136 | value *= pow(10.0, sig - 1 - exponent10); |
- | |
137 | fract = modf(value, &display); |
- | |
138 | if(fract >= 0.5){display += 1.0;} |
- | |
139 | value = display * pow(10.0, exponent10 - sig + 1); |
- | |
140 | if(exponent10 > 0){exponent10 = (exponent10/3)*3;}else{exponent10 = ((-exponent10+3)/3)*(-3);} |
- | |
141 | value *= pow(10.0, -exponent10); |
- | |
142 | if(format != 3){ /* allow all powers; not limited by prefix list */ |
- | |
143 |
|
126 | if(value>1){ |
144 |
|
127 | while(value >= 10){ |
145 |
|
128 | value=value / 10.0; |
146 |
|
129 | exponent10++; |
147 |
|
130 | /* need to set a limit to number of while loops ! */ |
148 |
|
131 | if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;} |
149 | } |
- | |
150 | } |
- | |
151 | } |
- | |
152 | else /* steps of powers dividable by 3 used for prefix notation */ |
- | |
153 | { |
- | |
154 | if (value >= 1000.0) { |
- | |
155 | value = value / 1000.0; |
- | |
156 | exponent10 = exponent10 + 3; |
- | |
157 | } |
- | |
158 | else |
- | |
159 | { |
- | |
160 | if(value >= 100.0){ |
- | |
161 | sig = sig - 2; |
- | |
162 | } |
- | |
163 | else |
- | |
164 | { |
- | |
165 | if(value >= 10.0){ |
- | |
166 | sig = sig - 1; |
- | |
167 | } |
- | |
168 | } |
- | |
169 | } |
- | |
170 | } |
132 | } |
171 | } |
133 | } |
172 | if(cnt > 1){fprintf(stdout,",");} |
- | |
173 | /* |
134 | else /* 0 < value < 1 --> exponent10 < 0 */ |
174 | if(exponent10 == 0 ){ |
- | |
175 | format = 3; /* do not use 1.23*10^0 */ |
- | |
176 | } |
- | |
177 | else |
- | |
178 | { |
135 | { |
179 |
|
136 | while(value < 1){ |
180 | format = 3;/* do not use 1.23*10^1 */ |
- | |
181 | value |
137 | value=value*10; |
182 |
|
138 | exponent10--; |
- | 139 | /* need to set a limit to number of while loops ! */ |
|
- | 140 | if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;} |
|
183 | } |
141 | } |
184 | else |
- | |
185 | { |
- | |
186 | if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){ |
- | |
187 | format = 1; /* if no prefix available, revert to html presentation */ |
- | |
188 | } |
- | |
189 | } |
- | |
190 | - | ||
191 | } |
142 | } |
- | 143 | if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){ |
|
- | 144 | format = 1; /* not in my list of prefixes ; print in html ! */ |
|
- | 145 | } |
|
- | 146 | sig = sig - 1; /* "%.*f" counts the "." */ |
|
- | 147 | if(cnt > 1){fprintf(stdout,",");}/* more than one conversion to do : make list */ |
|
192 |
|
148 | int idx=0;int exp=0; |
- | 149 | if(exponent10 == 0){format = 6;} /* no need for 2*10^0 */ |
|
- | 150 | if(sig < 0){sig = 0;} /* better be safe than sorry... */ |
|
193 |
|
151 | switch(format){ |
- | 152 | case 0: fprintf(stdout, "%s%.*f*10^%d", sign, sig, value, exponent10);break; |
|
- | 153 | case 1: fprintf(stdout, "%s%.*f×10<sup>%d</sup>", sign, sig, value, exponent10);break; |
|
- | 154 | case 2: fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig, value, exponent10);break; |
|
- | 155 | case 3: |
|
- | 156 | /* |
|
- | 157 | 1,1,3 -> 1 |
|
- | 158 | 10,1,3 -> 1*10^-2 k |
|
- | 159 | 100,1,3 -> 1*10^-1 k |
|
- | 160 | 1000,1,3 -> 1 k |
|
- | 161 | 10000,1,3 -> 1*10^1 k |
|
- | 162 | 100000,1,3 -> 1*10^2 k |
|
- | 163 | 1000000,1,3 -> 1 M |
|
- | 164 | 10000000,1,3 -> 1*10^1 M |
|
- | 165 | 100000000,1,3 -> 1*10^2 M |
|
- | 166 | 1000000000,1,3 -> 1 G |
|
- | 167 | 1,1,3 -> 1 |
|
- | 168 | 0.1,1,3 -> 1*10^-1 |
|
- | 169 | 0.01,1,3 -> 1*10^-2 |
|
- | 170 | 0.001,1,3 -> 1 m |
|
- | 171 | 0.0001,1,3 -> 1*10^-1 m |
|
- | 172 | 0.00001,1,3 -> 1*10^-2 m |
|
- | 173 | 0.000001,1,3 -> 1 µ |
|
- | 174 | 0.0000001,1,3-> 1*10^-1 µ |
|
- | 175 | 0.00000001,1,3-> 1*10^-2 µ |
|
- | 176 | 0.000000001,1,3-> 1 n |
|
- | 177 | */ |
|
- | 178 | exp = exponent10%3; |
|
- | 179 | idx = round(exponent10/3); |
|
- | 180 | if( exponent10 > 0 ){ |
|
194 | if |
181 | if(use_word == 0 ){ prefix = plus[idx]; } else { prefix = plus_word[idx]; } |
- | 182 | } |
|
- | 183 | else |
|
- | 184 | { |
|
- | 185 | if(use_word == 0){ prefix = min[-1*idx]; } else { prefix = min_word[-1*idx]; } |
|
- | 186 | } |
|
- | 187 | if( exp == 0){ |
|
195 | fprintf(stdout, "%s%.*f |
188 | fprintf(stdout, "%s%.*f %s",sign, sig, value,prefix); |
196 | } |
189 | } |
197 | else |
190 | else |
198 | { |
191 | { |
199 | if( format == 1 ){ /* html presentation */ |
- | |
200 | fprintf(stdout, "%s%.*f×10<sup>%d</sup>", sign, sig-1, value, exponent10); |
- | |
201 | } |
- | |
202 | else |
- | |
203 | { |
- | |
204 | if(format == 2 ){/* latex presentation */ |
- | |
205 | fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig-1, value, exponent10); |
- | |
206 | } |
- | |
207 | else |
- | |
208 | { /* mathml presentation */ |
- | |
209 |
|
192 | fprintf(stdout, "%s%.*f×10<sup>%d</sup> %s", sign, sig, value, exp, prefix); |
210 | } |
- | |
211 | } |
- | |
212 | } |
193 | } |
213 |
|
194 | break; |
214 |
|
195 | case 4: fprintf(stdout, "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mstyle id=\"wims_mathml\" mathsize=\"110%%\"><mn>%s%.*f</mn><mo>×</mo><msup><mn>10</mn><mn>%d</mn></msup></mstyle></math>", sign, sig, value, exponent10);break; |
215 |
|
196 | case 5: break; |
216 | fprintf(stdout |
197 | case 6: fprintf(stdout, "%s%.*f",sign,sig,value);break; |
- | 198 | default: break; |
|
217 | } |
199 | } |
218 | return NULL; |
200 | return NULL; |
219 | } |
201 | } |
220 | 202 | ||
221 | int main( int argc , char *argv[]){ |
203 | int main( int argc , char *argv[]){ |
Line 269... | Line 251... | ||
269 | if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));} |
251 | if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));} |
270 | if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));} |
252 | if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));} |
271 | number = atof(ptr); |
253 | number = atof(ptr); |
272 | break; |
254 | break; |
273 | case 1: significance = atoi(ptr); break; |
255 | case 1: significance = atoi(ptr); break; |
274 | case 2: type = atoi(ptr); if(type < 0 || type > |
256 | case 2: type = atoi(ptr); if(type < 0 || type > 5 ){type = 0;} break; |
275 | default: break; |
257 | default: break; |
276 | } |
258 | } |
277 | idx++; |
259 | idx++; |
278 | ptr = (char *) strtok(NULL,","); |
260 | ptr = (char *) strtok(NULL,","); |
279 | } |
261 | } |