Subversion Repositories wimsdev

Rev

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