Subversion Repositories wimsdev

Rev

Rev 5283 | Rev 5360 | 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
 
5213 schaersvoo 25
result is
26
1 line per input number
5283 schaersvoo 27
6 items per line:
5207 schaersvoo 28
 
5213 schaersvoo 29
item 1) real number of significant digits in number_x (eg without leading zeros)
5219 schaersvoo 30
 
5283 schaersvoo 31
item 2) number of digits left from decimal point or if no decimals: total number of digits (length)
5207 schaersvoo 32
 
5283 schaersvoo 33
item 3) number of digits right from decimal point
5207 schaersvoo 34
 
5283 schaersvoo 35
item 4) exponent base (if not present : 1)
5207 schaersvoo 36
 
5283 schaersvoo 37
item 5) exponent (if not present : 0)
5207 schaersvoo 38
 
5283 schaersvoo 39
item 6) indication : is the number correctly written ?  1 or 0  ( 000.1 is not correct...)
5227 schaersvoo 40
        scientiffic: [1-9.*] *10^exp : 1.2345*10^5 is OK ... 12.345*10^4 or 0.12345*10^6 is "NOK"
41
        a*10^b  : 1 <= a <= 9
5219 schaersvoo 42
 
43
remarks:
44
- exponent: any other base will be tolerated : 4*7^5  base=7 exponent=5 -> 1,0,1,0,7,5,1
5283 schaersvoo 45
- 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 46
 
47
ruleset:
48
120.2           : 4 significant digits
5283 schaersvoo 49
120.2000        : 7 significant digits
5356 schaersvoo 50
0.0000120       : 3 significant digits
5219 schaersvoo 51
scientiffic notation:
5227 schaersvoo 52
1.202*10^5      : 4 significant digits
53
1.20200*10^5    : 6 significant digits
5219 schaersvoo 54
 
5227 schaersvoo 55
 
5213 schaersvoo 56
*/
5207 schaersvoo 57
 
58
#include <stdio.h>
59
#include <stdlib.h>
60
#include <string.h>
61
#define MAX_DIGITS 64
62
#define MAX_CONV 64
63
 
5213 schaersvoo 64
void append(char* s, char c){
65
    int len = strlen(s);
66
    s[len] = c;
67
    s[len+1] = '\0';
68
}
5207 schaersvoo 69
 
70
int main( int argc , char *argv[]){
71
    if( argc < 2){
72
        fprintf(stdout,"syntax error\n");
73
        exit(0);
74
    }
75
    char word[MAX_DIGITS];
76
    char *input;
5213 schaersvoo 77
    char exp[MAX_DIGITS];
5283 schaersvoo 78
    int cnt,i,ok,length,zeros,sig1,sig2,found_digit,found_point,dec1,pow,found_power,found_multiply,points,base_start,base_end,bracket;
79
    const char *invalid_characters = "\n\"\',!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&;:~><?/\\|";
5207 schaersvoo 80
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
81
    cnt = 1;
82
    input = argv[cnt];
83
    while( input != NULL){
84
        if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
85
        length = strlen(input);
5219 schaersvoo 86
        if( length > MAX_DIGITS){
87
            fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS);
88
            return 0;
89
 
5207 schaersvoo 90
        }
91
        /* test for illegal characters */
92
        while (*input){
93
            if ( strchr(invalid_characters, *input) ){
94
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
95
                return 0;
96
            }
97
            input++;
98
        }
99
        input = argv[cnt];
5356 schaersvoo 100
        // better way to use strncpy
101
        strncpy( word, input, MAX_DIGITS - strlen(word)-1);
5207 schaersvoo 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 
5356 schaersvoo 144
                    fprintf(stdout,"last zero : sig1 - zeros = %d - %d\n",sig1,zeros );
5213 schaersvoo 145
                        sig1 = sig1 - zeros;
146
                        sig2++;
5219 schaersvoo 147
                        if(found_power == 1){zeros++;}
5207 schaersvoo 148
                    }
149
                    else
5219 schaersvoo 150
                    {              
151
                        // 1.000*10^5 -> 4 sig
5283 schaersvoo 152
                        if( found_point == 0 ){
5219 schaersvoo 153
                            sig1++;
154
                        }
155
                        else
156
                        {
5283 schaersvoo 157
                            sig2++;
5219 schaersvoo 158
                            if( found_digit == 1 ){ sig1++; }
159
                        }
5207 schaersvoo 160
                        zeros++;
161
                    }
162
                    break;
5283 schaersvoo 163
                case '.' : dec1 = length - i - pow - 1;found_point = 1;points++; break;
5213 schaersvoo 164
                case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
165
                case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
166
                case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
167
                case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
168
                case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
169
                case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
170
                case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
171
                case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
172
                case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
5207 schaersvoo 173
                default :  break;
174
            }
5283 schaersvoo 175
            if(found_power == 0 && bracket == 0){ append(exp,word[i]); } // maybe a power was used ?
176
            bracket = 0;
5207 schaersvoo 177
        }
5213 schaersvoo 178
 
5219 schaersvoo 179
        if( found_power > 1 || found_multiply > 1){ // 2*2 10^5^7
180
            fprintf(stdout,"error \n");
181
            return 0;
182
        }
183
 
184
        if( points > 1){ // "nonsense" number 1.23.45  or 1.23*10^1.5
5283 schaersvoo 185
            fprintf(stdout,"-1,-1,-1,-1,-1,-1\n");
5219 schaersvoo 186
        }
187
        else
188
        {
189
            // extra check for handling "special cases" 
5356 schaersvoo 190
            if(found_point == 1 && found_power == 0 && found_multiply == 0 && word[1] == '.'){ok = 1;}// just a decimal number 0.1233
191
            else
5227 schaersvoo 192
            if(found_point == 0 && found_power == 0){ sig2 = length;ok = 1; }   // just a number 12345
193
            else
5283 schaersvoo 194
            if(found_point == 0 && found_multiply == 0 && found_power == 1){ sig1 = 0; sig2 = 0 ; dec1 = 0; }   // 10^5
5227 schaersvoo 195
            else
5283 schaersvoo 196
            if(found_point == 1 && found_multiply == 0 && found_power == 1){ sig1 = 0; sig2 = 0 ; dec1 = 0; }   // 10^5.1
5227 schaersvoo 197
            else
5283 schaersvoo 198
            if(found_point == 0 && found_multiply == 1 && found_power == 1){ dec1 = 0; sig2 = length - zeros - pow;}    // 3*10^5
5356 schaersvoo 199
 
5227 schaersvoo 200
            if( found_power == 1){
201
                // find out if scientiffic number is correctly written ; ok=0 -> ok=1 
202
                // rule [1-9].[0-9]* x10^exp
203
                if( word[0] != '0' && word[1] == '.' ){ //  0.120*10^5 => 1.20*10^4
204
                    ok = 1;
205
                }
206
                else
207
                {
208
                    if( (word[0] == '-' || word[0] == '+' ) && word[1] != '0' && word[2] == '.' ){
209
                        ok = 1; // -1.2*10^5
210
                    }
211
                    else
212
                    {
213
                        if( found_point == 0 && found_multiply == 1 ){
214
                            if( word[1] == '*' ){ //4*10^5
215
                                ok = 1;
216
                            }
217
                            else
218
                            {
219
                                if( (word[0] == '-' || word[0] == '+' ) && word[2] == '*'){ //-4*10^5
220
                                    ok = 1;
221
                                }
222
                            }
223
                        }
224
                    }
225
                }
5219 schaersvoo 226
                int len = strlen(exp);// reverse appended char array ... 123+ --> +321
227
                char exponent[len];
228
                int w = len - 1;
229
                for(i = 0 ; i < len ; i++){
230
                    exponent[i] = exp[w];
231
                    w--;
232
                }
233
                exponent[len] = '\0';
234
                if(base_start != 0){ // find the base ( default base = 10 )
235
                    int c = 0;int s;
236
                    if(base_end == 0){ // 10^5
237
                        s = 0;
238
                    }
239
                    else
240
                    {
241
                        s = base_end + 1; // 1.25*10^5
242
                    }
243
                    char c_base[base_start - s]; // assign char array of correct size
244
                    for(i = s ; i < base_start ; i++){
245
                        c_base[c] = word[i];
246
                        c++;
247
                    }
248
                    c_base[c] = '\0';
5283 schaersvoo 249
                    fprintf(stdout,"%d,%d,%d,%s,%s,%d\n",sig1,sig2,dec1,c_base,exponent,ok);
5219 schaersvoo 250
                }
251
                else
252
                { // base = 10 : used 4e+5
5283 schaersvoo 253
                    fprintf(stdout,"%d,%d,%d,10,%s,%d\n",sig1,sig2,dec1,exponent,ok);
5219 schaersvoo 254
                }
5213 schaersvoo 255
            }
256
            else
5219 schaersvoo 257
            {   // no exponent : base = '1' exponent = '0'
258
                //several possible correct way of writing...
5283 schaersvoo 259
                if( ok == 0 && (  sig1 == sig2 + dec1 ) ){ ok  = 1; }
260
                fprintf(stdout,"%d,%d,%d,1,0,%d\n",sig1,sig2,dec1,ok);
5213 schaersvoo 261
            }
262
        }
5207 schaersvoo 263
        cnt++;
264
        input = argv[cnt];
265
    }
5219 schaersvoo 266
    return 0;
5207 schaersvoo 267
}