Subversion Repositories wimsdev

Rev

Rev 5207 | Rev 5219 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5207 Rev 5213
Line 4... Line 4...
4
* This is all amateur scriblings... So no copyrights.                           *
4
* This is all amateur scriblings... So no copyrights.                           *
5
* This source code file, and compiled objects derived from it,                  *
5
* This source code file, and compiled objects derived from it,                  *
6
* can be used and distributed without restriction, including for commercial use *
6
* can be used and distributed without restriction, including for commercial use *
7
* No warrenty whatsoever                                                        *
7
* No warrenty whatsoever                                                        *
8
*********************************************************************************
8
*********************************************************************************
-
 
9
syntax number_1 number2 number_3 ... number_n
9
 
10
 
-
 
11
example
-
 
12
!exec sigdigits 0001.0200 01.0200*10^-4 1.023*10^5
-
 
13
3,2,4,4,0,0
-
 
14
3,2,2,4,-4,0
-
 
15
4,3,1,3,5,1
10
 
16
 
11
usage:
17
result is
12
1) discard trailing zeros : use no flags (default)
18
1 line per input number
13
!exec sigdigits 1.10000 2.0001000 123.0100010000
-
 
14
2,1  
-
 
15
5,4  
19
6 items per line:
16
9,6
-
 
17
 
20
 
18
or use flag "0"
21
item 1) real number of significant digits in number_x (eg without leading zeros)
19
!exec sigdigits 1.10000,0 2.0001000,0 123.0100010000,0
22
item 2) real number of "significant decimals" (eg without trailing zero's)
20
2,1  
-
 
21
5,4  
-
 
22
9,6
-
 
23
 
23
 
24
2) include trailing zeros : use flag "1" (due to accuracy measurement...)
24
item 3) number of digits left from decimal point (including non-significant)
25
!exec sigdigits 1.10000,1 2.0001000,1 123.0100010000,1
25
        or if no decimals: total number of digits (length)
26
7,5
-
 
27
9,7
-
 
28
14,10
-
 
-
 
26
item 4) number of digits right from decimal point (including non-significant)
29
 
27
 
30
3) scientific notation allowed:
28
item 5) exponent (if not present : 0)
31
!exec sigdigits 1.2300000*10^15
-
 
32
3,2
-
 
33
!exec sigdigits 1.2300001*10^15
-
 
34
8,7
-
 
35
!exec sigdigits 1.2300000e+15
-
 
36
3,2
-
 
37
!exec sigdigits 1.2300001e+15
-
 
38
8,7
-
 
39
 
29
 
40
4) all other 'numbers' using pi,log,ln,sin,etc...will produce an error
30
item 6) indication : is the number correctly written ?  1 or 0  ( 000.1 is not correct...)
41
 
31
 
42
5)output "2 items per line"
-
 
43
    first item is total amount of significant digits
-
 
44
    second item is amount of decimals
32
exponent '10^' or 'e': 1.23*10^-4 1.23e-4
-
 
33
*/
45
 
34
 
46
6) no evaluation on the 'size' of the number is performed.
-
 
47
 
-
 
48
It can be used in an answer checkfile,
-
 
49
to check if the pupil uses the correct amount of significant digits in the reply .
-
 
50
Example:
-
 
51
A circle with "R=2.01 cm" has a surface area of ?
-
 
52
The 'math' answer is approx 12.69234847976812366271292553 cm2
-
 
53
The 'physics' answer is 12.7 ... using 3 significant digits
-
 
54
(due to the precision of the given R. note: there is no checking of the unit 'cm')
-
 
55
 
-
 
56
 
-
 
57
*/
-
 
58
#include <stdio.h>
35
#include <stdio.h>
59
#include <stdlib.h>
36
#include <stdlib.h>
60
#include <string.h>
37
#include <string.h>
61
#define MAX_DIGITS 64
38
#define MAX_DIGITS 64
62
#define MAX_CONV 64
39
#define MAX_CONV 64
63
 
40
 
-
 
41
void append(char* s, char c){
-
 
42
    int len = strlen(s);
-
 
43
    s[len] = c;
-
 
44
    s[len+1] = '\0';
-
 
45
}
64
 
46
 
65
int main( int argc , char *argv[]){
47
int main( int argc , char *argv[]){
66
    if( argc < 2){
48
    if( argc < 2){
67
        fprintf(stdout,"syntax error\n");
49
        fprintf(stdout,"syntax error\n");
68
        exit(0);
50
        exit(0);
69
    }
51
    }
70
    char word[MAX_DIGITS];
52
    char word[MAX_DIGITS];
71
    char *input;
53
    char *input;
-
 
54
    char exp[MAX_DIGITS];
72
    int use_all_zeros,cnt,i,length,zeros,significance,found_digit,found_point,decimals;
55
    int cnt,i,ok,length,zeros,sig1,sig2,found_digit,found_point,dec1,dec2,pow,found_power,found_multiply;
73
    const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
56
    const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
74
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
57
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
75
    cnt = 1;
58
    cnt = 1;
76
    input = argv[cnt];
59
    input = argv[cnt];
77
    while( input != NULL){
60
    while( input != NULL){
Line 84... Line 67...
84
        /* test for illegal characters */
67
        /* test for illegal characters */
85
        while (*input){
68
        while (*input){
86
            if ( strchr(invalid_characters, *input) ){
69
            if ( strchr(invalid_characters, *input) ){
87
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
70
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
88
                return 0;
71
                return 0;
89
            }
72
            }
90
            input++;
73
            input++;
91
        }
74
        }
92
        input = argv[cnt];
75
        input = argv[cnt];
93
        strncpy( word, input, length );
76
        strncpy( word, input, length );
94
        // reset
77
        // reset
95
        found_digit = 0;
78
        found_digit = 0;
96
        found_point = 0;
79
        found_point = 0;
97
        decimals = 0;
80
        found_power = 0;
98
        significance = 0;
81
        found_multiply = 0;
-
 
82
        sig1 = 0; // real significant digits
-
 
83
        dec1 = 0; // real "significant decimals" 
-
 
84
        sig2 = 0; // integer part [including leading zeros]
-
 
85
        dec2 = 0; // decimal part [including trailing zeros]
99
        zeros = 0;
86
        pow = 0; // exponent
100
        use_all_zeros = 0; // trailing zeros are not significant...unless
87
        zeros = 0; // leading or trailing zeros
-
 
88
        exp[0]='\0';
101
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
89
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
102
            switch( word[i] ){
90
            switch( word[i] ){
103
                case '*' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
91
                case '^' : found_power = 1;break;
104
                case 'e' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
92
                case '*' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
105
                case 'E' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
93
                case 'e' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
106
                case ',' : // signaling a flag '1'
-
 
107
                    if( i+1 < length ){
-
 
108
                        if(word[i + 1] == '1'){ use_all_zeros = 1;}
94
                case 'E' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
109
                    }
-
 
110
                    significance = 0;
-
 
111
                    decimals = 0;
-
 
112
                    found_digit = 0;
-
 
113
                    zeros = 0;
-
 
114
                    break;
-
 
115
                case '0' :
95
                case '0' :
116
                    if(i == 0){//last char
96
                    if(i == 0){//last char 
117
                        significance = significance - zeros;
97
                        sig1 = sig1 - zeros;
-
 
98
                        sig2++;
118
                    }
99
                    }
119
                    else
100
                    else
120
                    {
101
                    {
121
                        if( found_digit == 1 ){
102
                        if( found_point == 1 ){ sig2++; }
122
                            significance++;
-
 
123
                        }
-
 
124
                        else
-
 
125
                        {
-
 
126
                            if( found_point == 0 && use_all_zeros == 1){
103
                        if( found_digit == 1 ){ sig1++; }
127
                                significance++;
-
 
128
                            }
-
 
129
                        }
-
 
130
                        zeros++;
104
                        zeros++;
131
                    }
105
                    }
132
                    break;
106
                    break;
133
                case '.' : decimals = significance; found_point = 1; break;
107
                case '.' : dec1 = sig1; dec2 = length - i - pow - 1;found_point = 1; break;
134
                case '1' : significance++;found_digit = 1;zeros = 0; break;
108
                case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
135
                case '2' : significance++;found_digit = 1;zeros = 0; break;
109
                case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
136
                case '3' : significance++;found_digit = 1;zeros = 0; break;
110
                case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
137
                case '4' : significance++;found_digit = 1;zeros = 0; break;
111
                case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
138
                case '5' : significance++;found_digit = 1;zeros = 0; break;
112
                case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
139
                case '6' : significance++;found_digit = 1;zeros = 0; break;
113
                case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
140
                case '7' : significance++;found_digit = 1;zeros = 0; break;
114
                case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
141
                case '8' : significance++;found_digit = 1;zeros = 0; break;
115
                case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
142
                case '9' : significance++;found_digit = 1;zeros = 0; break;
116
                case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
143
                default :  break;
117
                default :  break;
144
            }
118
            }
-
 
119
           
-
 
120
            if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ?
145
        }
121
        }
-
 
122
       
-
 
123
        if(found_point == 0){ sig2 = length; }  // just a number 12345
-
 
124
        //several possible correct way of writing...
-
 
125
        if( ( sig1 == sig2 + dec2 ) || ( sig1 + dec1 == sig2 + dec2 ) || ( dec1 == dec2 && sig2 == 1 ) ){ ok  = 1; } else { ok = 0; }
-
 
126
       
-
 
127
        if( found_power == 1){ // reverse appended char array ... 123+ --> +321
-
 
128
            int len = strlen(exp);
-
 
129
            char exponent[len];
-
 
130
            int w = len - 1;
-
 
131
            for(i = 0 ; i < len ; i++){
-
 
132
                exponent[i] = exp[w];
-
 
133
                w--;
-
 
134
            }
-
 
135
            exponent[len] = '\0';
-
 
136
            if( found_multiply == 0 ){ // e+4 10^6 
-
 
137
                fprintf(stdout,"0,%d,%d,%d,%s,1\n",dec1,sig2,dec2,exponent);
-
 
138
            }
-
 
139
            else
-
 
140
            {   // 1.23e6 1.23*10^5     
-
 
141
                fprintf(stdout,"%d,%d,%d,%d,%s,%d\n",sig1,dec1,sig2,dec2,exponent,ok);
-
 
142
            }
-
 
143
        }
-
 
144
        else
-
 
145
        {
-
 
146
            fprintf(stdout,"%d,%d,%d,%d,0,%d\n",sig1,dec1,sig2,dec2,ok);
-
 
147
        }
146
        cnt++;
148
        cnt++;
147
        input = argv[cnt];
149
        input = argv[cnt];
148
        fprintf(stdout,"%d,%d\n",significance,decimals);
-
 
149
    }
150
    }
150
    return (0);
151
    return (0);
151
}
152
}