Rev 5213 | Rev 5227 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5213 | Rev 5219 | ||
---|---|---|---|
Line 6... | Line 6... | ||
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 | syntax number_1 number2 number_3 ... number_n |
9 | syntax number_1 number2 number_3 ... number_n |
10 | 10 | ||
- | 11 | Treats a number as string array : no numrical evaluation ! |
|
- | 12 | ||
11 | example |
13 | example |
12 | !exec sigdigits 0001. |
14 | !exec sigdigits 0001.23 1.230 1.2300 1.23e5 1.23*10^5 1.2300e5 01.23*10^5 1.2.3.4 |
- | 15 | 3,2,1,2,1,0,1 |
|
13 |
|
16 | 3,2,1,3,1,0,0 |
14 |
|
17 | 3,2,1,4,1,0,1 |
- | 18 | 3,2,1,2,10,5,1 |
|
- | 19 | 3,2,1,2,10,5,1 |
|
15 |
|
20 | 5,4,1,4,10,5,1 |
- | 21 | 3,2,2,2,10,5,0 |
|
- | 22 | -1,-1,-1,-1,-1,-1,-1 |
|
16 | 23 | ||
17 | result is |
24 | result is |
18 | 1 line per input number |
25 | 1 line per input number |
19 |
|
26 | 7 items per line: |
20 | 27 | ||
21 | item 1) real number of significant digits in number_x (eg without leading zeros) |
28 | item 1) real number of significant digits in number_x (eg without leading zeros) |
- | 29 | ||
22 | item 2) real number of "significant decimals" (eg without trailing zero's) |
30 | item 2) real number of "significant decimals" (eg without trailing zero's) |
23 | 31 | ||
24 | item 3) number of digits left from decimal point (including non-significant) |
32 | item 3) number of digits left from decimal point (including non-significant) |
25 | or if no decimals: total number of digits (length) |
33 | or if no decimals: total number of digits (length) |
26 | item 4) number of digits right from decimal point (including non-significant) |
34 | item 4) number of digits right from decimal point (including non-significant) |
27 | 35 | ||
- | 36 | item 5) exponent base (if not present : 1) |
|
- | 37 | ||
28 | item |
38 | item 6) exponent (if not present : 0) |
29 | 39 | ||
30 | item |
40 | item 7) indication : is the number correctly written ? 1 or 0 ( 000.1 is not correct...) |
- | 41 | ||
- | 42 | remarks: |
|
- | 43 | - exponent: any other base will be tolerated : 4*7^5 base=7 exponent=5 -> 1,0,1,0,7,5,1 |
|
- | 44 | - if number is 'nonsense' : -1,-1,-1,-1,-1,-1 (1.23.4567 10^1.23.4 ; number will produce NaN in other math software) |
|
31 | 45 | ||
- | 46 | ruleset: |
|
- | 47 | 120.2 : 4 significant digits |
|
- | 48 | 120.2000 : 4 significant digits |
|
- | 49 | 0120.2 : 4 significant digits |
|
- | 50 | scientiffic notation: |
|
- | 51 | 120.2*10^5 : 4 significant digits |
|
32 |
|
52 | 120.200*10^5 : 6 significant digits |
- | 53 | ||
33 | */ |
54 | */ |
34 | 55 | ||
35 | #include <stdio.h> |
56 | #include <stdio.h> |
36 | #include <stdlib.h> |
57 | #include <stdlib.h> |
37 | #include <string.h> |
58 | #include <string.h> |
Line 50... | Line 71... | ||
50 | exit(0); |
71 | exit(0); |
51 | } |
72 | } |
52 | char word[MAX_DIGITS]; |
73 | char word[MAX_DIGITS]; |
53 | char *input; |
74 | char *input; |
54 | char exp[MAX_DIGITS]; |
75 | char exp[MAX_DIGITS]; |
55 | int cnt,i,ok,length,zeros,sig1,sig2,found_digit,found_point,dec1,dec2,pow,found_power,found_multiply; |
76 | int cnt,i,ok,length,zeros,sig1,sig2,found_digit,found_point,dec1,dec2,pow,found_power,found_multiply,points,base_start,base_end; |
56 | const char *invalid_characters = "\n\"\' |
77 | const char *invalid_characters = "\n\"\',!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|"; |
57 | /* Ee +- are allowed : 12.34e+05 12.34e-08 1.234*10^123*/ |
78 | /* Ee +- are allowed : 12.34e+05 12.34e-08 1.234*10^123*/ |
58 | cnt = 1; |
79 | cnt = 1; |
59 | input = argv[cnt]; |
80 | input = argv[cnt]; |
60 | while( input != NULL){ |
81 | while( input != NULL){ |
61 | if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;} |
82 | if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;} |
62 | length = strlen(input); |
83 | length = strlen(input); |
63 | if( length > MAX_DIGITS){ |
84 | if( length > MAX_DIGITS){ |
64 | fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS); |
85 | fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS); |
- | 86 | return 0; |
|
65 |
|
87 | |
66 | } |
88 | } |
67 | /* test for illegal characters */ |
89 | /* test for illegal characters */ |
68 | while (*input){ |
90 | while (*input){ |
69 | if ( strchr(invalid_characters, *input) ){ |
91 | if ( strchr(invalid_characters, *input) ){ |
70 | fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input); |
92 | fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input); |
71 | return 0; |
93 | return 0; |
72 | } |
94 | } |
73 | input++; |
95 | input++; |
74 | } |
96 | } |
75 | input = argv[cnt]; |
97 | input = argv[cnt]; |
76 | strncpy( word, input, length ); |
98 | strncpy( word, input, length ); |
77 | // reset |
99 | // reset |
78 | found_digit = 0; |
100 | found_digit = 0; |
79 | found_point = 0; |
101 | found_point = 0; |
Line 83... | Line 105... | ||
83 | dec1 = 0; // real "significant decimals" |
105 | dec1 = 0; // real "significant decimals" |
84 | sig2 = 0; // integer part [including leading zeros] |
106 | sig2 = 0; // integer part [including leading zeros] |
85 | dec2 = 0; // decimal part [including trailing zeros] |
107 | dec2 = 0; // decimal part [including trailing zeros] |
86 | pow = 0; // exponent |
108 | pow = 0; // exponent |
87 | zeros = 0; // leading or trailing zeros |
109 | zeros = 0; // leading or trailing zeros |
- | 110 | points = 0; // number of points in number... |
|
88 | exp[0]='\0'; |
111 | exp[0]='\0'; |
- | 112 | base_start = 0; |
|
- | 113 | base_end = 0; |
|
89 | for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number' |
114 | for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number' |
90 | switch( word[i] ){ |
115 | switch( word[i] ){ |
91 | case '^' : |
116 | case '^' : base_start = i;found_power++;break; |
- | 117 | case '*' : |
|
- | 118 | found_multiply++; |
|
- | 119 | if(found_power == 1){ |
|
- | 120 | base_end = i; |
|
92 |
|
121 | if(found_point == 1){points--;found_point = 0;} // point in exponent... 10^4.5 (hmmm) |
- | 122 | pow = length - i; |
|
- | 123 | sig1 = 0; // reset counting significant digits and all other stuff |
|
- | 124 | dec1 = 0; |
|
- | 125 | sig2 = 0; |
|
- | 126 | dec2 = 0; |
|
- | 127 | found_digit = 0; |
|
- | 128 | zeros = 0; |
|
- | 129 | } |
|
- | 130 | break; |
|
93 | case 'e' : |
131 | case 'e' : if(found_point == 1){points--;found_point = 0;} found_power++;pow = length - i;sig1 = 0;dec1 = 0;sig2 = 0;dec2 = 0;found_digit = 0;zeros = 0;found_multiply++;break; |
94 | case 'E' : |
132 | case 'E' : if(found_point == 1){points--;found_point = 0;} found_power++;pow = length - i;sig1 = 0;dec1 = 0;sig2 = 0;dec2 = 0;found_digit = 0;zeros = 0;found_multiply++;break; |
95 | case '0' : |
133 | case '0' : |
96 | if(i == 0){//last char |
134 | if(i == 0){//last char |
97 | sig1 = sig1 - zeros; |
135 | sig1 = sig1 - zeros; |
98 | sig2++; |
136 | sig2++; |
- | 137 | if(found_power == 1){zeros++;} |
|
99 | } |
138 | } |
100 | else |
139 | else |
101 | { |
140 | { |
- | 141 | // 1.000*10^5 -> 4 sig |
|
- | 142 | if( found_point == 0 && found_power == 1){ |
|
- | 143 | sig1++; |
|
- | 144 | } |
|
- | 145 | else |
|
- | 146 | { |
|
- | 147 | if( found_digit == 1 ){ sig1++; } |
|
- | 148 | } |
|
102 | if( found_point == 1 ){ sig2++; } |
149 | if( found_point == 1 ){ sig2++; } |
103 | if( found_digit == 1 ){ sig1++; } |
- | |
104 | zeros++; |
150 | zeros++; |
105 | } |
151 | } |
106 | break; |
152 | break; |
107 | case '.' : dec1 = sig1; dec2 = length - i - pow - 1;found_point = 1; break; |
153 | case '.' : dec1 = sig1; dec2 = length - i - pow - 1;found_point = 1;points++; break; |
108 | case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
154 | case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
109 | case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
155 | case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
110 | case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
156 | case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
111 | case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
157 | case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
112 | case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
158 | case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
113 | case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
159 | case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
114 | case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
160 | case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
115 | case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
161 | case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
116 | case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
162 | case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break; |
117 | default : break; |
163 | default : break; |
118 | } |
164 | } |
119 | - | ||
120 | if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ? |
165 | if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ? |
121 | } |
166 | } |
122 | 167 | ||
123 | if(found_point == 0){ sig2 = length; } // just a number 12345 |
- | |
124 | //several possible correct way of writing... |
- | |
125 | if( ( sig1 == sig2 + dec2 ) || ( sig1 + dec1 == sig2 + dec2 ) || ( dec1 == dec2 && sig2 == 1 ) ){ ok = 1; } else { ok = 0; } |
- | |
126 | - | ||
127 | if( found_power |
168 | if( found_power > 1 || found_multiply > 1){ // 2*2 10^5^7 |
128 |
|
169 | fprintf(stdout,"error \n"); |
129 | char exponent[len]; |
- | |
130 |
|
170 | return 0; |
131 | for(i = 0 ; i < len ; i++){ |
- | |
132 | exponent[i] = exp[w]; |
- | |
133 | w--; |
- | |
134 |
|
171 | } |
135 | exponent[len] = '\0'; |
- | |
136 | if( found_multiply == 0 ){ // e+4 10^6 |
- | |
137 | fprintf(stdout,"0,%d,%d,%d,%s,1\n",dec1,sig2,dec2,exponent); |
- | |
138 | } |
172 | |
139 | else |
- | |
140 |
|
173 | if( points > 1){ // "nonsense" number 1.23.45 or 1.23*10^1.5 |
141 |
|
174 | fprintf(stdout,"-1,-1,-1,-1,-1,-1,-1\n"); |
142 | } |
- | |
143 | } |
175 | } |
144 | else |
176 | else |
145 | { |
177 | { |
- | 178 | // extra check for handling "special cases" |
|
- | 179 | if(found_point == 0 && found_power == 0){ sig2 = length; } // just a number 12345 |
|
- | 180 | if(found_point == 0 && found_multiply == 0 && found_power == 1){ sig1 = 0; dec1 = 0; sig2 = 0 ; dec2 = 0; } // 10^5 |
|
- | 181 | if(found_point == 1 && found_multiply == 0 && found_power == 1){ sig1 = 0; dec1 = 0; sig2 = 0 ; dec2 = 0; } // 10^5.1 |
|
- | 182 | if(found_point == 0 && found_multiply == 1 && found_power == 1){ dec1 = 0; dec2 = 0; sig2 = length - zeros - pow; } // 3*10^5 |
|
- | 183 | ||
- | 184 | if( found_power == 1){ |
|
- | 185 | // correct writing ? 1.20000*10^5 is OK, 01.20000*10^5 is NOK |
|
- | 186 | if( zeros != 0 ){ ok = 0; }else{ ok = 1; } // 01*10^5 |
|
- | 187 | int len = strlen(exp);// reverse appended char array ... 123+ --> +321 |
|
- | 188 | char exponent[len]; |
|
- | 189 | int w = len - 1; |
|
- | 190 | for(i = 0 ; i < len ; i++){ |
|
- | 191 | exponent[i] = exp[w]; |
|
- | 192 | w--; |
|
- | 193 | } |
|
- | 194 | exponent[len] = '\0'; |
|
- | 195 | if(base_start != 0){ // find the base ( default base = 10 ) |
|
- | 196 | int c = 0;int s; |
|
- | 197 | if(base_end == 0){ // 10^5 |
|
- | 198 | s = 0; |
|
- | 199 | } |
|
- | 200 | else |
|
- | 201 | { |
|
- | 202 | s = base_end + 1; // 1.25*10^5 |
|
- | 203 | } |
|
- | 204 | char c_base[base_start - s]; // assign char array of correct size |
|
- | 205 | for(i = s ; i < base_start ; i++){ |
|
- | 206 | c_base[c] = word[i]; |
|
- | 207 | c++; |
|
- | 208 | } |
|
- | 209 | c_base[c] = '\0'; |
|
- | 210 | fprintf(stdout,"%d,%d,%d,%d,%s,%s,%d\n",sig1,dec1,sig2,dec2,c_base,exponent,ok); |
|
- | 211 | } |
|
- | 212 | else |
|
- | 213 | { // base = 10 : used 4e+5 |
|
- | 214 | fprintf(stdout,"%d,%d,%d,%d,10,%s,%d\n",sig1,dec1,sig2,dec2,exponent,ok); |
|
- | 215 | } |
|
- | 216 | } |
|
- | 217 | else |
|
- | 218 | { // no exponent : base = '1' exponent = '0' |
|
- | 219 | //several possible correct way of writing... |
|
- | 220 | if( ( sig1 == sig2 + dec2 ) || ( sig1 + dec1 == sig2 + dec2 ) || ( dec1 == dec2 && sig2 == 1 ) ){ ok = 1; } else { ok = 0; } |
|
146 | fprintf(stdout," |
221 | fprintf(stdout,"%d,%d,%d,%d,1,0,%d\n",sig1,dec1,sig2,dec2,ok); |
- | 222 | } |
|
147 | } |
223 | } |
148 | cnt++; |
224 | cnt++; |
149 | input = argv[cnt]; |
225 | input = argv[cnt]; |
150 | } |
226 | } |
151 | return |
227 | return 0; |
152 | } |
228 | } |