Subversion Repositories wimsdev

Rev

Rev 5207 | Rev 5219 | 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
 
5213 schaersvoo 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
5207 schaersvoo 16
 
5213 schaersvoo 17
result is
18
1 line per input number
19
6 items per line:
5207 schaersvoo 20
 
5213 schaersvoo 21
item 1) real number of significant digits in number_x (eg without leading zeros)
22
item 2) real number of "significant decimals" (eg without trailing zero's)
5207 schaersvoo 23
 
5213 schaersvoo 24
item 3) number of digits left from decimal point (including non-significant)
25
        or if no decimals: total number of digits (length)
26
item 4) number of digits right from decimal point (including non-significant)
5207 schaersvoo 27
 
5213 schaersvoo 28
item 5) exponent (if not present : 0)
5207 schaersvoo 29
 
5213 schaersvoo 30
item 6) indication : is the number correctly written ?  1 or 0  ( 000.1 is not correct...)
5207 schaersvoo 31
 
5213 schaersvoo 32
exponent '10^' or 'e': 1.23*10^-4 1.23e-4
33
*/
5207 schaersvoo 34
 
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#define MAX_DIGITS 64
39
#define MAX_CONV 64
40
 
5213 schaersvoo 41
void append(char* s, char c){
42
    int len = strlen(s);
43
    s[len] = c;
44
    s[len+1] = '\0';
45
}
5207 schaersvoo 46
 
47
int main( int argc , char *argv[]){
48
    if( argc < 2){
49
        fprintf(stdout,"syntax error\n");
50
        exit(0);
51
    }
52
    char word[MAX_DIGITS];
53
    char *input;
5213 schaersvoo 54
    char exp[MAX_DIGITS];
55
    int cnt,i,ok,length,zeros,sig1,sig2,found_digit,found_point,dec1,dec2,pow,found_power,found_multiply;
5207 schaersvoo 56
    const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
57
    /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
58
    cnt = 1;
59
    input = argv[cnt];
60
    while( input != NULL){
61
        if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
62
        length = strlen(input);
63
        if( length > MAX_DIGITS){                                                                                                          
64
            fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS);                                                            
65
            exit(0);                                                                                                                      
66
        }
67
        /* test for illegal characters */
68
        while (*input){
69
            if ( strchr(invalid_characters, *input) ){
70
                fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
71
                return 0;
72
            }
73
            input++;
74
        }
75
        input = argv[cnt];
76
        strncpy( word, input, length );
77
        // reset
78
        found_digit = 0;
79
        found_point = 0;
5213 schaersvoo 80
        found_power = 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]
86
        pow = 0; // exponent
87
        zeros = 0; // leading or trailing zeros
88
        exp[0]='\0';
5207 schaersvoo 89
        for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
90
            switch( word[i] ){
5213 schaersvoo 91
                case '^' : found_power = 1;break;
92
                case '*' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
93
                case 'e' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
94
                case 'E' : found_power = 1;pow = length - i;sig1 = 0;dec1 = 0;found_digit = 0;zeros = 0;found_multiply = 1;break;
5207 schaersvoo 95
                case '0' :
5213 schaersvoo 96
                    if(i == 0){//last char 
97
                        sig1 = sig1 - zeros;
98
                        sig2++;
5207 schaersvoo 99
                    }
100
                    else
101
                    {
5213 schaersvoo 102
                        if( found_point == 1 ){ sig2++; }
103
                        if( found_digit == 1 ){ sig1++; }
5207 schaersvoo 104
                        zeros++;
105
                    }
106
                    break;
5213 schaersvoo 107
                case '.' : dec1 = sig1; dec2 = length - i - pow - 1;found_point = 1; break;
108
                case '1' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
109
                case '2' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
110
                case '3' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
111
                case '4' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
112
                case '5' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
113
                case '6' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
114
                case '7' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
115
                case '8' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
116
                case '9' : sig1++;if(found_point == 1){sig2++;} found_digit = 1;zeros = 0; break;
5207 schaersvoo 117
                default :  break;
118
            }
5213 schaersvoo 119
 
120
            if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ?
5207 schaersvoo 121
        }
5213 schaersvoo 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
        }
5207 schaersvoo 148
        cnt++;
149
        input = argv[cnt];
150
    }
151
    return (0);
152
}