Rev 14856 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3519 | schaersvoo | 1 | /* |
2 | ********************************************************************************* |
||
14857 | bpr | 3 | * J.M. Evers 3/2012 * |
4 | * This is all amateur scriblings... So no copyrights. * |
||
5 | * This source code file, and compiled objects derived from it, * |
||
6 | * can be used and distributed without restriction, including for commercial use * |
||
7 | * No warrenty whatsoever * |
||
3519 | schaersvoo | 8 | ********************************************************************************* |
13932 | schaersvoo | 9 | general use: |
10 | rounding to 2 decimals (financial math) |
||
11 | tot=!exec moneyprint 0.1,17,123.4,123.99765 |
||
12 | tot -> 0.10,17.00,123.40,124.00 |
||
5416 | schaersvoo | 13 | |
5154 | schaersvoo | 14 | 2/2012 |
15 | modified for general rounding usage; a word 'DECIMALS' can be added to the list of numbers |
||
5416 | schaersvoo | 16 | tot=!exec moneyprint 2.1,4.123,5 2 // 2 decimals |
17 | tot -> 2.10,4.12,5.00 |
||
18 | tot=!exec moneyprint 2.1,4.123,5 4 // 4 decimals |
||
19 | tot -> 2.1000,4.1230,5.0000 |
||
20 | tot=!exec moneyprint 2.1,4.123,5 |
||
14857 | bpr | 21 | tot -> 2.10,4.12,5.00 //default value (or old syntax) is 2 decimals |
5154 | schaersvoo | 22 | |
13932 | schaersvoo | 23 | 6/2012. |
5416 | schaersvoo | 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 |
||
26 | tot -> 1.235e06,1.235e6,0.012e-23 |
||
14857 | bpr | 27 | |
5416 | schaersvoo | 28 | assumed only powers of 10 [scientific notation] |
14857 | bpr | 29 | |
6273 | schaersvoo | 30 | 12/2012 |
14857 | bpr | 31 | Modified : using only 10^ in powers |
13932 | schaersvoo | 32 | (e+8 -> *10^8 ; e-8 -> *10^-8) |
33 | Extra syntax error signal (using more than 1 'e') |
||
6273 | schaersvoo | 34 | |
8346 | schaersvoo | 35 | 27/2014 |
13932 | schaersvoo | 36 | Modified avoiding truncating of numbers like 15.625 --> 16.62 |
14856 | schaersvoo | 37 | 4/2020 |
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 |
||
3519 | schaersvoo | 40 | */ |
8346 | schaersvoo | 41 | |
14856 | schaersvoo | 42 | |
3519 | schaersvoo | 43 | #include <stdio.h> |
44 | #include <stdlib.h> |
||
45 | #include <string.h> |
||
8346 | schaersvoo | 46 | #include <math.h> |
13932 | schaersvoo | 47 | #define MAX_DIGITS 32 |
5416 | schaersvoo | 48 | #define MAX_CONV 32 |
3519 | schaersvoo | 49 | |
14857 | bpr | 50 | int main( int argc, char *argv[]){ |
51 | if( argc != 2 && argc != 3){ |
||
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 | exit(0); |
||
54 | } |
||
55 | /* test for illegal characters */ |
||
56 | const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWYZabcdfghijklmnopqrstuvwyz@#$%&()[]{}:~><?/\\|"; |
||
57 | /* ;+-*^XxEe are allowed : 12.34e+05 12.34e-08 1x10^5 1.234*10^123*/ |
||
58 | char *input; |
||
59 | input = argv[1]; |
||
60 | while (*input){ |
||
61 | if ( strchr(invalid_characters, *input) ){ |
||
62 | fprintf(stdout,"error !\nfound illegal character \"%c\" in argument\n",*input); |
||
63 | exit(0); |
||
13932 | schaersvoo | 64 | } |
14857 | bpr | 65 | input++; |
66 | } |
||
67 | int DECIMALS; |
||
68 | if(argv[2] != NULL){ |
||
69 | DECIMALS = atoi(argv[2]); |
||
70 | if(DECIMALS > MAX_DIGITS){ |
||
71 | fprintf(stdout,"error ! maximum amount of decimals is %d \n",MAX_DIGITS);exit(0); |
||
13932 | schaersvoo | 72 | } |
14857 | bpr | 73 | } |
74 | else DECIMALS = 2; |
||
75 | char *ptr; |
||
76 | char word[MAX_DIGITS]; |
||
77 | char exponent[MAX_DIGITS]; |
||
78 | char number[MAX_DIGITS]; |
||
79 | int cnt = 0; |
||
80 | int powE = 0; |
||
81 | int idx1 = 0; |
||
82 | int idx2 = 0; |
||
83 | int length= 0; |
||
84 | int i = 0; |
||
85 | int pow10 = 0; |
||
86 | double correction = 1/(pow(10,DECIMALS+6)); /* a reasonable guess...to avoid truncating 15.625 --> 16.63 */ |
||
87 | double ascii_number; |
||
88 | input = argv[1]; |
||
89 | /* 14/4/2020 replace ';' by ',' BPR */ |
||
90 | int idx3[MAX_CONV]; |
||
91 | for(i = 0; i < strlen(input); i++){ |
||
92 | if(input[i] == ';'){ |
||
93 | input[i] = ','; idx3[cnt] = 1; cnt++; |
||
13932 | schaersvoo | 94 | } |
95 | else |
||
14857 | bpr | 96 | if(input[i] == ',' ){ idx3[cnt] = 0; cnt++;} |
97 | } |
||
98 | char *sep = ","; |
||
99 | cnt = 1; |
||
100 | ptr = strtok(input,","); |
||
101 | while( ptr != NULL){ |
||
102 | if( cnt > MAX_CONV ){ |
||
103 | fprintf(stdout,"ERROR too many (> %d)conversion \n",MAX_CONV); |
||
104 | exit(0); |
||
13932 | schaersvoo | 105 | } |
14857 | bpr | 106 | /* next item in input argv[1] */ |
107 | strncpy( word, ptr, MAX_DIGITS-1); |
||
108 | length = strlen(ptr); |
||
109 | if(length > MAX_DIGITS-1){ |
||
110 | fprintf(stdout,"ERROR string too large\n"); |
||
111 | exit(0); |
||
112 | } |
||
113 | /* reset counters */ |
||
114 | powE = 0; |
||
115 | pow10 = 0; |
||
116 | idx1 = 0; |
||
117 | idx2 = 0; |
||
118 | i = 0; |
||
119 | for( i = 0; i < length ; i++){ |
||
120 | if(powE > 1 ){ |
||
121 | fprintf(stdout,"ERROR in syntax\n"); |
||
122 | exit(0); |
||
14856 | schaersvoo | 123 | } |
14857 | bpr | 124 | if( idx1 + idx2 > MAX_DIGITS-1){ |
125 | fprintf(stdout,"ERROR string too large\n"); |
||
126 | exit(0); |
||
127 | } |
||
128 | switch( word[i] ){ |
||
129 | case '+' : break; /* do not use 10^+2 */ |
||
130 | case 'e' : powE++;break; |
||
131 | case 'E' : powE++;break; |
||
132 | case 'x' : pow10++;break; |
||
133 | case '*' : pow10++;break; |
||
134 | case '^' : pow10=5;break; |
||
135 | default : |
||
136 | if( pow10 > 0 ){ |
||
137 | pow10++; |
||
138 | if( pow10 > 4 ){ /* *10^ = 4 chars */ |
||
139 | exponent[idx2] = word[i]; |
||
140 | idx2++; |
||
141 | } |
||
13932 | schaersvoo | 142 | } |
143 | else |
||
144 | { |
||
14857 | bpr | 145 | if(powE > 0){ |
146 | exponent[idx2] = word[i]; idx2++;} |
||
147 | else { |
||
148 | number[idx1] = word[i]; idx1++;} |
||
13932 | schaersvoo | 149 | } |
14857 | bpr | 150 | break; |
151 | } |
||
13932 | schaersvoo | 152 | } |
14857 | bpr | 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; |
||
160 | if( powE == 1 || pow10> 0 ){ |
||
161 | if(cnt > 1) |
||
162 | fprintf( stdout, "%s%.*f*10^%s", sep, DECIMALS, ascii_number, exponent ); |
||
163 | else |
||
164 | fprintf( stdout, "%.*f*10^%s", DECIMALS, ascii_number, exponent ); |
||
165 | } |
||
166 | else { |
||
167 | if(cnt > 1 ) |
||
168 | fprintf( stdout, "%s%.*f", sep, DECIMALS, ascii_number); |
||
169 | else |
||
170 | fprintf( stdout, "%.*f", DECIMALS, ascii_number); |
||
171 | } |
||
172 | if(idx3[cnt-1] == 1 ) sep = ";"; else sep = ","; |
||
173 | cnt++; |
||
174 | ptr = strtok(NULL,","); |
||
175 | } |
||
176 | fprintf(stdout,"\n"); |
||
177 | return 0; |
||
3519 | schaersvoo | 178 | } |