Subversion Repositories wimsdev

Rev

Rev 5227 | Rev 5356 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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