Subversion Repositories wimsdev

Rev

Rev 5213 | Go to most recent revision | Details | 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
*********************************************************************************
9
 
10
 
11
usage:
12
1) discard trailing zeros : use no flags (default)
13
!exec sigdigits 1.10000 2.0001000 123.0100010000
14
2,1  
15
5,4  
16
9,6
17
 
18
or use flag "0"
19
!exec sigdigits 1.10000,0 2.0001000,0 123.0100010000,0
20
2,1  
21
5,4  
22
9,6
23
 
24
2) include trailing zeros : use flag "1" (due to accuracy measurement...)
25
!exec sigdigits 1.10000,1 2.0001000,1 123.0100010000,1
26
7,5
27
9,7
28
14,10
29
 
30
3) scientific notation allowed:
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
 
40
4) all other 'numbers' using pi,log,ln,sin,etc...will produce an error
41
 
42
5)output "2 items per line"
43
    first item is total amount of significant digits
44
    second item is amount of decimals
45
 
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>
59
#include <stdlib.h>
60
#include <string.h>
61
#define MAX_DIGITS 64
62
#define MAX_CONV 64
63
 
64
 
65
int main( int argc , char *argv[]){
66
    if( argc < 2){
67
        fprintf(stdout,"syntax error\n");
68
        exit(0);
69
    }
70
    char word[MAX_DIGITS];
71
    char *input;
72
    int use_all_zeros,cnt,i,length,zeros,significance,found_digit,found_point,decimals;
73
    const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
74
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
75
    cnt = 1;
76
    input = argv[cnt];
77
    while( input != NULL){
78
        if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
79
        length = strlen(input);
80
        if( length > MAX_DIGITS){                                                                                                          
81
            fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS);                                                            
82
            exit(0);                                                                                                                      
83
        }
84
        /* test for illegal characters */
85
        while (*input){
86
            if ( strchr(invalid_characters, *input) ){
87
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
88
                return 0;
89
            }
90
            input++;
91
        }
92
        input = argv[cnt];
93
        strncpy( word, input, length );
94
        // reset
95
        found_digit = 0;
96
        found_point = 0;
97
        decimals = 0;
98
        significance = 0;
99
        zeros = 0;
100
        use_all_zeros = 0; // trailing zeros are not significant...unless
101
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
102
            switch( word[i] ){
103
                case '*' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
104
                case 'e' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
105
                case 'E' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
106
                case ',' : // signaling a flag '1'
107
                    if( i+1 < length ){
108
                        if(word[i + 1] == '1'){ use_all_zeros = 1;}
109
                    }
110
                    significance = 0;
111
                    decimals = 0;
112
                    found_digit = 0;
113
                    zeros = 0;
114
                    break;
115
                case '0' :
116
                    if(i == 0){//last char
117
                        significance = significance - zeros;
118
                    }
119
                    else
120
                    {
121
                        if( found_digit == 1 ){
122
                            significance++;
123
                        }
124
                        else
125
                        {
126
                            if( found_point == 0 && use_all_zeros == 1){
127
                                significance++;
128
                            }
129
                        }
130
                        zeros++;
131
                    }
132
                    break;
133
                case '.' : decimals = significance; found_point = 1; break;
134
                case '1' : significance++;found_digit = 1;zeros = 0; break;
135
                case '2' : significance++;found_digit = 1;zeros = 0; break;
136
                case '3' : significance++;found_digit = 1;zeros = 0; break;
137
                case '4' : significance++;found_digit = 1;zeros = 0; break;
138
                case '5' : significance++;found_digit = 1;zeros = 0; break;
139
                case '6' : significance++;found_digit = 1;zeros = 0; break;
140
                case '7' : significance++;found_digit = 1;zeros = 0; break;
141
                case '8' : significance++;found_digit = 1;zeros = 0; break;
142
                case '9' : significance++;found_digit = 1;zeros = 0; break;
143
                default :  break;
144
            }
145
        }
146
        cnt++;
147
        input = argv[cnt];
148
        fprintf(stdout,"%d,%d\n",significance,decimals);
149
    }
150
    return (0);
151
}