Subversion Repositories wimsdev

Rev

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.0200 01.0200*10^-4 1.023*10^5
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
3,2,4,4,0,0
16
3,2,1,3,1,0,0
14
3,2,2,4,-4,0
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
4,3,1,3,5,1
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
6 items per line:
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 5) exponent (if not present : 0)
38
item 6) exponent (if not present : 0)
29
 
39
 
30
item 6) indication : is the number correctly written ?  1 or 0  ( 000.1 is not correct...)
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
exponent '10^' or 'e': 1.23*10^-4 1.23e-4
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\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
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
            exit(0);                                                                                                                      
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 '^' : found_power = 1;break;
116
                case '^' : base_start = i;found_power++;break;
-
 
117
                case '*' :
-
 
118
                    found_multiply++;
-
 
119
                    if(found_power == 1){
-
 
120
                        base_end = i;
92
                case '*' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
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' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
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' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
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 == 1){ // reverse appended char array ... 123+ --> +321
168
        if( found_power > 1 || found_multiply > 1){ // 2*2 10^5^7
128
            int len = strlen(exp);
169
            fprintf(stdout,"error \n");
129
            char exponent[len];
-
 
130
            int w = len - 1;
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
            {   // 1.23e6 1.23*10^5     
173
        if( points > 1){ // "nonsense" number 1.23.45  or 1.23*10^1.5
141
                fprintf(stdout,"%d,%d,%d,%d,%s,%d\n",sig1,dec1,sig2,dec2,exponent,ok);
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,"%d,%d,%d,%d,0,%d\n",sig1,dec1,sig2,dec2,ok);
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 (0);
227
    return 0;
152
}
228
}