Subversion Repositories wimsdev

Rev

Rev 5213 | Rev 5227 | 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
 
5219 schaersvoo 11
Treats a number as string array : no numrical evaluation !
12
 
5213 schaersvoo 13
example
5219 schaersvoo 14
!exec sigdigits 1.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
16
3,2,1,3,1,0,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
20
5,4,1,4,10,5,1
21
3,2,2,2,10,5,0
22
-1,-1,-1,-1,-1,-1,-1
5207 schaersvoo 23
 
5213 schaersvoo 24
result is
25
1 line per input number
5219 schaersvoo 26
7 items per line:
5207 schaersvoo 27
 
5213 schaersvoo 28
item 1) real number of significant digits in number_x (eg without leading zeros)
5219 schaersvoo 29
 
5213 schaersvoo 30
item 2) real number of "significant decimals" (eg without trailing zero's)
5207 schaersvoo 31
 
5213 schaersvoo 32
item 3) number of digits left from decimal point (including non-significant)
33
        or if no decimals: total number of digits (length)
34
item 4) number of digits right from decimal point (including non-significant)
5207 schaersvoo 35
 
5219 schaersvoo 36
item 5) exponent base (if not present : 1)
5207 schaersvoo 37
 
5219 schaersvoo 38
item 6) exponent (if not present : 0)
5207 schaersvoo 39
 
5219 schaersvoo 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)
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
52
120.200*10^5    : 6 significant digits
53
 
5213 schaersvoo 54
*/
5207 schaersvoo 55
 
56
#include <stdio.h>
57
#include <stdlib.h>
58
#include <string.h>
59
#define MAX_DIGITS 64
60
#define MAX_CONV 64
61
 
5213 schaersvoo 62
void append(char* s, char c){
63
    int len = strlen(s);
64
    s[len] = c;
65
    s[len+1] = '\0';
66
}
5207 schaersvoo 67
 
68
int main( int argc , char *argv[]){
69
    if( argc < 2){
70
        fprintf(stdout,"syntax error\n");
71
        exit(0);
72
    }
73
    char word[MAX_DIGITS];
74
    char *input;
5213 schaersvoo 75
    char exp[MAX_DIGITS];
5219 schaersvoo 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;
77
    const char *invalid_characters = "\n\"\',!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
5207 schaersvoo 78
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
79
    cnt = 1;
80
    input = argv[cnt];
81
    while( input != NULL){
82
        if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
83
        length = strlen(input);
5219 schaersvoo 84
        if( length > MAX_DIGITS){
85
            fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS);
86
            return 0;
87
 
5207 schaersvoo 88
        }
89
        /* test for illegal characters */
90
        while (*input){
91
            if ( strchr(invalid_characters, *input) ){
92
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
93
                return 0;
94
            }
95
            input++;
96
        }
97
        input = argv[cnt];
98
        strncpy( word, input, length );
99
        // reset
100
        found_digit = 0;
101
        found_point = 0;
5213 schaersvoo 102
        found_power = 0;
103
        found_multiply = 0;
104
        sig1 = 0; // real significant digits
105
        dec1 = 0; // real "significant decimals" 
106
        sig2 = 0; // integer part [including leading zeros]
107
        dec2 = 0; // decimal part [including trailing zeros]
108
        pow = 0; // exponent
109
        zeros = 0; // leading or trailing zeros
5219 schaersvoo 110
        points = 0; // number of points in number...
5213 schaersvoo 111
        exp[0]='\0';
5219 schaersvoo 112
        base_start = 0;
113
        base_end = 0;
5207 schaersvoo 114
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
115
            switch( word[i] ){
5219 schaersvoo 116
                case '^' : base_start = i;found_power++;break;
117
                case '*' :
118
                    found_multiply++;
119
                    if(found_power == 1){
120
                        base_end = i;
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;
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;
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;
5207 schaersvoo 133
                case '0' :
5213 schaersvoo 134
                    if(i == 0){//last char 
135
                        sig1 = sig1 - zeros;
136
                        sig2++;
5219 schaersvoo 137
                        if(found_power == 1){zeros++;}
5207 schaersvoo 138
                    }
139
                    else
5219 schaersvoo 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
                        }
5213 schaersvoo 149
                        if( found_point == 1 ){ sig2++; }
5207 schaersvoo 150
                        zeros++;
151
                    }
152
                    break;
5219 schaersvoo 153
                case '.' : dec1 = sig1; dec2 = length - i - pow - 1;found_point = 1;points++; break;
5213 schaersvoo 154
                case '1' : 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;
156
                case '3' : 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;
158
                case '5' : 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;
160
                case '7' : 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;
162
                case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
5207 schaersvoo 163
                default :  break;
164
            }
5213 schaersvoo 165
            if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ?
5207 schaersvoo 166
        }
5213 schaersvoo 167
 
5219 schaersvoo 168
        if( found_power > 1 || found_multiply > 1){ // 2*2 10^5^7
169
            fprintf(stdout,"error \n");
170
            return 0;
171
        }
172
 
173
        if( points > 1){ // "nonsense" number 1.23.45  or 1.23*10^1.5
174
            fprintf(stdout,"-1,-1,-1,-1,-1,-1,-1\n");
175
        }
176
        else
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
                }
5213 schaersvoo 216
            }
217
            else
5219 schaersvoo 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; }
221
                fprintf(stdout,"%d,%d,%d,%d,1,0,%d\n",sig1,dec1,sig2,dec2,ok);
5213 schaersvoo 222
            }
223
        }
5207 schaersvoo 224
        cnt++;
225
        input = argv[cnt];
226
    }
5219 schaersvoo 227
    return 0;
5207 schaersvoo 228
}