Subversion Repositories wimsdev

Rev

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
 
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;
5207 schaersvoo 89
        }
90
        /* test for illegal characters */
91
        while (*input){
92
            if ( strchr(invalid_characters, *input) ){
93
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
94
                return 0;
95
            }
96
            input++;
97
        }
98
        input = argv[cnt];
5356 schaersvoo 99
        // better way to use strncpy
100
        strncpy( word, input, MAX_DIGITS - strlen(word)-1);
5207 schaersvoo 101
        // reset
102
        found_digit = 0;
103
        found_point = 0;
5213 schaersvoo 104
        found_power = 0;
5283 schaersvoo 105
        bracket = 0;
5213 schaersvoo 106
        found_multiply = 0;
107
        sig1 = 0; // real significant digits
108
        sig2 = 0; // integer part [including leading zeros]
5283 schaersvoo 109
        dec1 = 0; // decimal part [including trailing zeros]
5213 schaersvoo 110
        pow = 0; // exponent
111
        zeros = 0; // leading or trailing zeros
5219 schaersvoo 112
        points = 0; // number of points in number...
5213 schaersvoo 113
        exp[0]='\0';
5219 schaersvoo 114
        base_start = 0;
115
        base_end = 0;
5227 schaersvoo 116
        ok = 0;
5207 schaersvoo 117
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
118
            switch( word[i] ){
5283 schaersvoo 119
                case '(' : bracket = 1 ;break; //  10^(-4) -> exp= (-4) : remove bracket from exponent.
120
                case ')' : bracket = 1 ;break;
121
                case '{' : bracket = 1 ;break;
122
                case '}' : bracket = 1 ;break;
123
                case '[' : bracket = 1 ;break;
124
                case ']' : bracket = 1 ;break;
5219 schaersvoo 125
                case '^' : base_start = i;found_power++;break;
126
                case '*' :
127
                    found_multiply++;
128
                    if(found_power == 1){
129
                        base_end = i;
130
                        if(found_point == 1){points--;found_point = 0;}  // point in exponent... 10^4.5 (hmmm)
131
                        pow = length - i;
132
                        sig1 = 0; // reset counting significant digits and all other stuff
133
                        sig2 = 0;
5283 schaersvoo 134
                        dec1 = 0;
5219 schaersvoo 135
                        found_digit = 0;
136
                        zeros = 0;
137
                    }
138
                    break;
5283 schaersvoo 139
                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;
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;
5207 schaersvoo 141
                case '0' :
5213 schaersvoo 142
                    if(i == 0){//last char 
143
                        sig1 = sig1 - zeros;
144
                        sig2++;
5219 schaersvoo 145
                        if(found_power == 1){zeros++;}
5207 schaersvoo 146
                    }
147
                    else
5219 schaersvoo 148
                    {              
149
                        // 1.000*10^5 -> 4 sig
5283 schaersvoo 150
                        if( found_point == 0 ){
5219 schaersvoo 151
                            sig1++;
152
                        }
153
                        else
154
                        {
5283 schaersvoo 155
                            sig2++;
5219 schaersvoo 156
                            if( found_digit == 1 ){ sig1++; }
157
                        }
5207 schaersvoo 158
                        zeros++;
159
                    }
160
                    break;
5283 schaersvoo 161
                case '.' : dec1 = length - i - pow - 1;found_point = 1;points++; break;
5213 schaersvoo 162
                case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
163
                case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
164
                case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
165
                case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
166
                case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
167
                case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
168
                case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
169
                case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
170
                case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
5207 schaersvoo 171
                default :  break;
172
            }
5283 schaersvoo 173
            if(found_power == 0 && bracket == 0){ append(exp,word[i]); } // maybe a power was used ?
174
            bracket = 0;
5207 schaersvoo 175
        }
5213 schaersvoo 176
 
5219 schaersvoo 177
        if( found_power > 1 || found_multiply > 1){ // 2*2 10^5^7
178
            fprintf(stdout,"error \n");
179
            return 0;
180
        }
181
 
182
        if( points > 1){ // "nonsense" number 1.23.45  or 1.23*10^1.5
5283 schaersvoo 183
            fprintf(stdout,"-1,-1,-1,-1,-1,-1\n");
5219 schaersvoo 184
        }
185
        else
186
        {
187
            // extra check for handling "special cases" 
5356 schaersvoo 188
            if(found_point == 1 && found_power == 0 && found_multiply == 0 && word[1] == '.'){ok = 1;}// just a decimal number 0.1233
189
            else
5227 schaersvoo 190
            if(found_point == 0 && found_power == 0){ sig2 = length;ok = 1; }   // just a number 12345
191
            else
5283 schaersvoo 192
            if(found_point == 0 && found_multiply == 0 && found_power == 1){ sig1 = 0; sig2 = 0 ; dec1 = 0; }   // 10^5
5227 schaersvoo 193
            else
5283 schaersvoo 194
            if(found_point == 1 && found_multiply == 0 && found_power == 1){ sig1 = 0; sig2 = 0 ; dec1 = 0; }   // 10^5.1
5227 schaersvoo 195
            else
5283 schaersvoo 196
            if(found_point == 0 && found_multiply == 1 && found_power == 1){ dec1 = 0; sig2 = length - zeros - pow;}    // 3*10^5
5356 schaersvoo 197
 
5227 schaersvoo 198
            if( found_power == 1){
199
                // find out if scientiffic number is correctly written ; ok=0 -> ok=1 
200
                // rule [1-9].[0-9]* x10^exp
201
                if( word[0] != '0' && word[1] == '.' ){ //  0.120*10^5 => 1.20*10^4
202
                    ok = 1;
203
                }
204
                else
205
                {
206
                    if( (word[0] == '-' || word[0] == '+' ) && word[1] != '0' && word[2] == '.' ){
207
                        ok = 1; // -1.2*10^5
208
                    }
209
                    else
210
                    {
211
                        if( found_point == 0 && found_multiply == 1 ){
212
                            if( word[1] == '*' ){ //4*10^5
213
                                ok = 1;
214
                            }
215
                            else
216
                            {
217
                                if( (word[0] == '-' || word[0] == '+' ) && word[2] == '*'){ //-4*10^5
218
                                    ok = 1;
219
                                }
220
                            }
221
                        }
222
                    }
223
                }
5219 schaersvoo 224
                int len = strlen(exp);// reverse appended char array ... 123+ --> +321
225
                char exponent[len];
226
                int w = len - 1;
227
                for(i = 0 ; i < len ; i++){
228
                    exponent[i] = exp[w];
229
                    w--;
230
                }
231
                exponent[len] = '\0';
232
                if(base_start != 0){ // find the base ( default base = 10 )
233
                    int c = 0;int s;
234
                    if(base_end == 0){ // 10^5
235
                        s = 0;
236
                    }
237
                    else
238
                    {
239
                        s = base_end + 1; // 1.25*10^5
240
                    }
241
                    char c_base[base_start - s]; // assign char array of correct size
242
                    for(i = s ; i < base_start ; i++){
243
                        c_base[c] = word[i];
244
                        c++;
245
                    }
246
                    c_base[c] = '\0';
5283 schaersvoo 247
                    fprintf(stdout,"%d,%d,%d,%s,%s,%d\n",sig1,sig2,dec1,c_base,exponent,ok);
5219 schaersvoo 248
                }
249
                else
250
                { // base = 10 : used 4e+5
5283 schaersvoo 251
                    fprintf(stdout,"%d,%d,%d,10,%s,%d\n",sig1,sig2,dec1,exponent,ok);
5219 schaersvoo 252
                }
5213 schaersvoo 253
            }
254
            else
5219 schaersvoo 255
            {   // no exponent : base = '1' exponent = '0'
256
                //several possible correct way of writing...
5283 schaersvoo 257
                if( ok == 0 && (  sig1 == sig2 + dec1 ) ){ ok  = 1; }
258
                fprintf(stdout,"%d,%d,%d,1,0,%d\n",sig1,sig2,dec1,ok);
5213 schaersvoo 259
            }
260
        }
5207 schaersvoo 261
        cnt++;
262
        input = argv[cnt];
263
    }
5219 schaersvoo 264
    return 0;
5207 schaersvoo 265
}