Rev 14856 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 14856 | Rev 14857 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | ********************************************************************************* |
2 | ********************************************************************************* |
3 | * J.M. Evers 3/2012 |
3 | * J.M. Evers 3/2012 * |
4 | * This is all amateur scriblings... So no copyrights. |
4 | * This is all amateur scriblings... So no copyrights. * |
5 | * This source code file, and compiled objects derived from it, |
5 | * This source code file, and compiled objects derived from it, * |
6 | * can be used and distributed without restriction, including for commercial use * |
6 | * can be used and distributed without restriction, including for commercial use * |
7 | * No warrenty whatsoever |
7 | * No warrenty whatsoever * |
8 | ********************************************************************************* |
8 | ********************************************************************************* |
9 | general use: |
9 | general use: |
10 | rounding to 2 decimals (financial math) |
10 | rounding to 2 decimals (financial math) |
11 | tot=!exec moneyprint 0.1,17,123.4,123.99765 |
11 | tot=!exec moneyprint 0.1,17,123.4,123.99765 |
12 | tot -> 0.10,17.00,123.40,124.00 |
12 | tot -> 0.10,17.00,123.40,124.00 |
Line 16... | Line 16... | ||
16 | tot=!exec moneyprint 2.1,4.123,5 2 // 2 decimals |
16 | tot=!exec moneyprint 2.1,4.123,5 2 // 2 decimals |
17 | tot -> 2.10,4.12,5.00 |
17 | tot -> 2.10,4.12,5.00 |
18 | tot=!exec moneyprint 2.1,4.123,5 4 // 4 decimals |
18 | tot=!exec moneyprint 2.1,4.123,5 4 // 4 decimals |
19 | tot -> 2.1000,4.1230,5.0000 |
19 | tot -> 2.1000,4.1230,5.0000 |
20 | tot=!exec moneyprint 2.1,4.123,5 |
20 | tot=!exec moneyprint 2.1,4.123,5 |
21 | tot -> 2.10,4.12,5.00 //default value (or old syntax) is 2 decimals |
21 | tot -> 2.10,4.12,5.00 //default value (or old syntax) is 2 decimals |
22 | 22 | ||
23 | 6/2012. |
23 | 6/2012. |
24 | modified again to support rounding of scientific numbers, like |
24 | modified again to support rounding of scientific numbers, like |
25 | tot=!exec moneyprint 1.23456e+06,1.23456*10^6,0.01234e-23 3 |
25 | tot=!exec moneyprint 1.23456e+06,1.23456*10^6,0.01234e-23 3 |
26 | tot -> 1.235e06,1.235e6,0.012e-23 |
26 | tot -> 1.235e06,1.235e6,0.012e-23 |
27 | |
27 | |
28 | assumed only powers of 10 [scientific notation] |
28 | assumed only powers of 10 [scientific notation] |
29 | |
29 | |
30 | 12/2012 |
30 | 12/2012 |
31 | Modified : using only 10^ in powers |
31 | Modified : using only 10^ in powers |
32 | (e+8 -> *10^8 ; e-8 -> *10^-8) |
32 | (e+8 -> *10^8 ; e-8 -> *10^-8) |
33 | Extra syntax error signal (using more than 1 'e') |
33 | Extra syntax error signal (using more than 1 'e') |
34 | 34 | ||
35 | 27/2014 |
35 | 27/2014 |
36 | Modified avoiding truncating of numbers like 15.625 --> 16.62 |
36 | Modified avoiding truncating of numbers like 15.625 --> 16.62 |
37 | 4/2020 |
37 | 4/2020 |
38 | Modified to use ";" and "," as separators...preserving the sequence |
38 | Modified to use ";" and "," as separators...preserving the sequence |
39 | moneyprint 1,2,3;4,5,6;7,8,9 -> 1.00,2.00,3.00;4.00,5.00,6.00;7.00,8.00,9.00 |
39 | moneyprint 1,2,3;4,5,6;7,8,9 -> 1.00,2.00,3.00;4.00,5.00,6.00;7.00,8.00,9.00 |
Line 45... | Line 45... | ||
45 | #include <string.h> |
45 | #include <string.h> |
46 | #include <math.h> |
46 | #include <math.h> |
47 | #define MAX_DIGITS 32 |
47 | #define MAX_DIGITS 32 |
48 | #define MAX_CONV 32 |
48 | #define MAX_CONV 32 |
49 | 49 | ||
50 | int main( int argc |
50 | int main( int argc, char *argv[]){ |
51 |
|
51 | if( argc != 2 && argc != 3){ |
52 |
|
52 | fprintf(stdout,"error !\nusage:\n!exec moneyprint $your_wims_item_list $precision_word\nexample:\nmoney=!exec moneyprint 1.2,30.1,.4,-.23123456 2\nThe result is a comma separated list: 1.20,30.10,0.40,-0.23\n using 2 decimals\nNote: no calculations are done.\nNo spaces allowed \n"); |
53 |
|
53 | exit(0); |
54 |
|
54 | } |
55 |
|
55 | /* test for illegal characters */ |
56 |
|
56 | const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWYZabcdfghijklmnopqrstuvwyz@#$%&()[]{}:~><?/\\|"; |
57 |
|
57 | /* ;+-*^XxEe are allowed : 12.34e+05 12.34e-08 1x10^5 1.234*10^123*/ |
58 |
|
58 | char *input; |
59 |
|
59 | input = argv[1]; |
60 |
|
60 | while (*input){ |
61 |
|
61 | if ( strchr(invalid_characters, *input) ){ |
62 |
|
62 | fprintf(stdout,"error !\nfound illegal character \"%c\" in argument\n",*input); |
63 |
|
63 | exit(0); |
64 |
|
64 | } |
65 |
|
65 | input++; |
66 |
|
66 | } |
67 |
|
67 | int DECIMALS; |
68 |
|
68 | if(argv[2] != NULL){ |
69 |
|
69 | DECIMALS = atoi(argv[2]); |
70 |
|
70 | if(DECIMALS > MAX_DIGITS){ |
71 |
|
71 | fprintf(stdout,"error ! maximum amount of decimals is %d \n",MAX_DIGITS);exit(0); |
72 |
|
72 | } |
73 |
|
73 | } |
74 |
|
74 | else DECIMALS = 2; |
75 |
|
75 | char *ptr; |
76 |
|
76 | char word[MAX_DIGITS]; |
77 |
|
77 | char exponent[MAX_DIGITS]; |
78 |
|
78 | char number[MAX_DIGITS]; |
79 |
|
79 | int cnt = 0; |
80 |
|
80 | int powE = 0; |
81 |
|
81 | int idx1 = 0; |
82 |
|
82 | int idx2 = 0; |
83 |
|
83 | int length= 0; |
84 |
|
84 | int i = 0; |
85 |
|
85 | int pow10 = 0; |
86 |
|
86 | double correction = 1/(pow(10,DECIMALS+6)); /* a reasonable guess...to avoid truncating 15.625 --> 16.63 */ |
87 |
|
87 | double ascii_number; |
88 |
|
88 | input = argv[1]; |
89 |
|
89 | /* 14/4/2020 replace ';' by ',' BPR */ |
90 |
|
90 | int idx3[MAX_CONV]; |
91 |
|
91 | for(i = 0; i < strlen(input); i++){ |
92 |
|
92 | if(input[i] == ';'){ |
93 |
|
93 | input[i] = ','; idx3[cnt] = 1; cnt++; |
94 |
|
94 | } |
95 |
|
95 | else |
96 |
|
96 | if(input[i] == ',' ){ idx3[cnt] = 0; cnt++;} |
97 |
|
97 | } |
98 |
|
98 | char *sep = ","; |
99 |
|
99 | cnt = 1; |
100 |
|
100 | ptr = strtok(input,","); |
101 |
|
101 | while( ptr != NULL){ |
102 |
|
102 | if( cnt > MAX_CONV ){ |
103 |
|
103 | fprintf(stdout,"ERROR too many (> %d)conversion \n",MAX_CONV); |
104 |
|
104 | exit(0); |
105 |
|
105 | } |
106 |
|
106 | /* next item in input argv[1] */ |
107 | |
107 | strncpy( word, ptr, MAX_DIGITS-1); |
108 |
|
108 | length = strlen(ptr); |
109 |
|
109 | if(length > MAX_DIGITS-1){ |
110 |
|
110 | fprintf(stdout,"ERROR string too large\n"); |
111 |
|
111 | exit(0); |
112 |
|
112 | } |
113 |
|
113 | /* reset counters */ |
114 |
|
114 | powE = 0; |
115 |
|
115 | pow10 = 0; |
116 |
|
116 | idx1 = 0; |
117 |
|
117 | idx2 = 0; |
118 |
|
118 | i = 0; |
119 |
|
119 | for( i = 0; i < length ; i++){ |
120 |
|
120 | if(powE > 1 ){ |
121 |
|
121 | fprintf(stdout,"ERROR in syntax\n"); |
122 | |
122 | exit(0); |
123 |
|
123 | } |
124 |
|
124 | if( idx1 + idx2 > MAX_DIGITS-1){ |
125 |
|
125 | fprintf(stdout,"ERROR string too large\n"); |
126 |
|
126 | exit(0); |
127 |
|
127 | } |
128 |
|
128 | switch( word[i] ){ |
129 |
|
129 | case '+' : break; /* do not use 10^+2 */ |
130 |
|
130 | case 'e' : powE++;break; |
131 |
|
131 | case 'E' : powE++;break; |
132 |
|
132 | case 'x' : pow10++;break; |
133 |
|
133 | case '*' : pow10++;break; |
134 |
|
134 | case '^' : pow10=5;break; |
135 |
|
135 | default : |
136 |
|
136 | if( pow10 > 0 ){ |
137 |
|
137 | pow10++; |
138 |
|
138 | if( pow10 > 4 ){ /* *10^ = 4 chars */ |
139 |
|
139 | exponent[idx2] = word[i]; |
140 |
|
140 | idx2++; |
141 |
|
141 | } |
142 | case 'x' : pow10++;break; |
- | |
143 | case '*' : pow10++;break; |
- | |
144 | case '^' : pow10=5;break; |
- | |
145 | default : |
- | |
146 | if( pow10 > 0 ){ |
- | |
147 | pow10++; |
- | |
148 | if( pow10 > 4 ){ /* *10^ = 4 chars */ |
- | |
149 | exponent[idx2] = word[i]; |
- | |
150 | idx2++; |
- | |
151 | } |
- | |
152 | } |
- | |
153 | else |
- | |
154 | { |
- | |
155 | if(powE > 0){ |
- | |
156 | exponent[idx2] = word[i]; |
- | |
157 | idx2++; |
- | |
158 | } |
- | |
159 | else |
- | |
160 | { |
- | |
161 | number[idx1] = word[i]; |
- | |
162 | idx1++; |
- | |
163 | } |
- | |
164 | } |
- | |
165 | break; |
- | |
166 | } |
- | |
167 | } |
- | |
168 | exponent[idx2] = '\0'; |
- | |
169 | number[idx1] = '\0'; |
- | |
170 | ascii_number = atof(number); |
- | |
171 | if( ascii_number > 0 ){ |
- | |
172 | ascii_number = ascii_number + correction; |
- | |
173 | } |
142 | } |
174 | else |
143 | else |
175 | { |
144 | { |
- | 145 | if(powE > 0){ |
|
- | 146 | exponent[idx2] = word[i]; idx2++;} |
|
- | 147 | else { |
|
176 |
|
148 | number[idx1] = word[i]; idx1++;} |
177 | } |
149 | } |
- | 150 | break; |
|
- | 151 | } |
|
- | 152 | } |
|
- | 153 | exponent[idx2] = '\0'; |
|
- | 154 | number[idx1] = '\0'; |
|
- | 155 | ascii_number = atof(number); |
|
- | 156 | if( ascii_number > 0 ) |
|
- | 157 | ascii_number = ascii_number + correction; |
|
- | 158 | else |
|
- | 159 | ascii_number = ascii_number - correction; |
|
178 |
|
160 | if( powE == 1 || pow10> 0 ){ |
179 |
|
161 | if(cnt > 1) |
180 |
|
162 | fprintf( stdout, "%s%.*f*10^%s", sep, DECIMALS, ascii_number, exponent ); |
181 | } |
- | |
182 |
|
163 | else |
183 | { |
- | |
184 |
|
164 | fprintf( stdout, "%.*f*10^%s", DECIMALS, ascii_number, exponent ); |
185 |
|
165 | } |
186 | } |
- | |
187 |
|
166 | else { |
188 | { |
- | |
189 |
|
167 | if(cnt > 1 ) |
190 |
|
168 | fprintf( stdout, "%s%.*f", sep, DECIMALS, ascii_number); |
191 | } |
- | |
192 |
|
169 | else |
193 | { |
- | |
194 |
|
170 | fprintf( stdout, "%.*f", DECIMALS, ascii_number); |
195 | } |
- | |
196 | } |
- | |
197 | if(idx3[cnt-1] == 1 ){sep = ";";}else{sep = ",";} |
- | |
198 | cnt++; |
- | |
199 | ptr = strtok(NULL,","); |
- | |
200 | } |
171 | } |
- | 172 | if(idx3[cnt-1] == 1 ) sep = ";"; else sep = ","; |
|
- | 173 | cnt++; |
|
- | 174 | ptr = strtok(NULL,","); |
|
- | 175 | } |
|
201 |
|
176 | fprintf(stdout,"\n"); |
202 |
|
177 | return 0; |
203 | } |
178 | } |
204 | - |