Subversion Repositories wimsdev

Rev

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

Rev 7038 Rev 7076
Line 2... Line 2...
2
 
2
 
3
*********************************************************************************
3
*********************************************************************************
4
* J.M. Evers 3/2012                                                             *
4
* J.M. Evers 3/2012                                                             *
5
* This is all amateur scriblings... So no copyrights.                           *
5
* This is all amateur scriblings... So no copyrights.                           *
6
* This source code file, and compiled objects derived from it,                  *
6
* This source code file, and compiled objects derived from it,                  *
7
* can be used and distributed without restriction, including for commercial use *
7
* can be used and distributed without restriction, including for commercial use *
8
* No warrenty whatsoever                                                        *
8
* No warrenty whatsoever                                                        *
9
*********************************************************************************
9
*********************************************************************************
10
20/6/2012
10
20/6/2012
11
Corrected significance flaw when using prefixes
11
Corrected significance flaw when using prefixes
12
Simplified routines
12
Simplified routines
13
Added type = 5 : prefix-notation with words (nano,mega,giga...etc)
13
Added type = 5 : prefix-notation with words (nano,mega,giga...etc)
Line 41... Line 41...
41
default  : calc   notation : 120000,3   -> 1.20*10^5
41
default  : calc   notation : 120000,3   -> 1.20*10^5
42
type = 0 : calc   notation : 120000,3,0 -> 1.20*10^5
42
type = 0 : calc   notation : 120000,3,0 -> 1.20*10^5
43
type = 1 : html notation   : 120000,3,1 -> 1.20&times;10<sup>5</sup>
43
type = 1 : html notation   : 120000,3,1 -> 1.20&times;10<sup>5</sup>
44
type = 2 : latex notation  : 120000,3,2 -> 1.20 \times 10^{5}
44
type = 2 : latex notation  : 120000,3,2 -> 1.20 \times 10^{5}
45
type = 3 : prefix-notation : 120000,3,3 -> 120.0 k
45
type = 3 : prefix-notation : 120000,3,3 -> 120.0 k
46
type = 3 : if -24 > prefix > 24         -> type = 1 (html)
46
type = 3 : if -24 > prefix > 24         -> type = 1 (html)
47
type = 4 : mathml notation
47
type = 4 : mathml notation
48
 
48
 
49
multiple conversion: use space between arguments
49
multiple conversion: use space between arguments
50
scienceprint 120000,4 122900,5 120036,6,3 --> 120.0*10^3,122.90*10^3,120.036 k
50
scienceprint 120000,4 122900,5 120036,6,3 --> 120.0*10^3,122.90*10^3,120.036 k
51
 
51
 
52
24  yotta       Y
52
24  yotta       Y
53
21  zetta       Z
53
21  zetta       Z
54
18  exa         E
54
18  exa         E
55
15  peta        P
55
15  peta        P
56
12  tera        T
56
12  tera        T
57
9   giga        G
57
9   giga        G
58
6   mega        M
58
6   mega        M
59
3   kilo        k
59
3   kilo        k
60
 
60
 
61
2   hecto       h
61
2   hecto       h
62
1   deca        da
62
1   deca        da
63
-1  deci        d
63
-1  deci        d
64
-2  centi       c
64
-2  centi       c
65
 
65
 
66
-3  milli       m
66
-3  milli       m
67
-6  micro       µ
67
-6  micro       µ
68
-9  nano        n
68
-9  nano        n
69
-12 pico        p
69
-12 pico        p
70
-15 femto       f
70
-15 femto       f
71
-18 atto        a
71
-18 atto        a
72
-21 zepto       z
72
-21 zepto       z
73
-24 yocto       y
73
-24 yocto       y
74
 
74
 
75
*/
75
*/
76
 
76
 
77
#include <stdio.h>
77
#include <stdio.h>
78
#include <math.h>
78
#include <math.h>
Line 93... Line 93...
93
    /* if either sub_word or rep_word is NULL, duplicate word a let caller handle it */
93
    /* if either sub_word or rep_word is NULL, duplicate word a let caller handle it */
94
    if ( sub_word == NULL || rep_word == NULL ) return strdup(word);
94
    if ( sub_word == NULL || rep_word == NULL ) return strdup(word);
95
    new_word = strdup (word);
95
    new_word = strdup (word);
96
    head = new_word;
96
    head = new_word;
97
    while ( (part_word = strstr ( head, sub_word ))){
97
    while ( (part_word = strstr ( head, sub_word ))){
98
        old_word = new_word;
98
        old_word = new_word;
99
        new_word = malloc ( strlen ( old_word ) - strlen ( sub_word ) + strlen ( rep_word ) + 1 );
99
        new_word = malloc ( strlen ( old_word ) - strlen ( sub_word ) + strlen ( rep_word ) + 1 );
100
        /*failed to alloc mem, free old word and return NULL */
100
        /*failed to alloc mem, free old word and return NULL */
101
        if ( new_word == NULL ){
101
        if ( new_word == NULL ){
102
          free (old_word);return NULL;
102
          free (old_word);return NULL;
103
        }
103
        }
Line 115... Line 115...
115
char *printscience(double value, int sig, int format , int cnt ,int size){
115
char *printscience(double value, int sig, int format , int cnt ,int size){
116
    static char *min[] = {"","m",MICRO,"n","p","f","a","z","y"};
116
    static char *min[] = {"","m",MICRO,"n","p","f","a","z","y"};
117
    static char *plus[] = {"","k", "M", "G", "T", "P", "E", "Z", "Y" };
117
    static char *plus[] = {"","k", "M", "G", "T", "P", "E", "Z", "Y" };
118
    static char *min_word[] = {"","milli","micro","nano","pico","femto","atto","zepto","yocto"};
118
    static char *min_word[] = {"","milli","micro","nano","pico","femto","atto","zepto","yocto"};
119
    static char *plus_word[] = {"","kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta" };
119
    static char *plus_word[] = {"","kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta" };
120
    char *sign = NULL;char *prefix = NULL;int pm;int factor;
120
    char *sign = NULL;char *prefix = NULL;double pm;int factor;
121
    int exponent10 = 0;
121
    int exponent10 = 0;
122
    int use_word = 0;if(format == 5){format = 3; use_word = 1;} /* switch to using words in stead of prefix  */
122
    int use_word = 0;if(format == 5){format = 3; use_word = 1;} /* switch to using words in stead of prefix  */
123
    if(value < 0.0) {pm = -0.5; sign = "-";value = -value;} else {sign = ""; pm = 0.5;}    
123
    if(value < 0.0) {pm = -0.5; sign = "-";value = -value;} else {sign = ""; pm = 0.5;}    
124
    if( sig == -1 ){
124
    if( sig == -1 ){
125
     /*
125
     /*
126
     no significance truncations...just science notation 1234 -> 1.234*10^3
126
     no significance truncations...just science notation 1234 -> 1.234*10^3
127
     try (!) to use same amount of digits
127
     try (!) to use same amount of digits
128
     */
128
     */
129
        sig = size;
129
        sig = size;
130
        if(format == 3){format = 1;} /* never prefix --> html notation */
130
        if(format == 3){format = 1;} /* never prefix --> html notation */
131
    }
131
    }
132
    if(value == 0){fprintf(stdout, "%s%.*f", sign, sig-1, value);return NULL;} /* no need to go further */
132
    if(value == 0){fprintf(stdout, "%s%.*f", sign, sig-1, value);return NULL;} /* no need to go further */
133
    if(value>1){
133
    if(value>1){
134
        while(value >= 10){
134
        while(value >= 10){
135
            value=value / 10.0;
135
            value=value / 10.0;
136
            exponent10++;
136
            exponent10++;
137
            /* need to set a limit to number of while loops ! */
137
            /* need to set a limit to number of while loops ! */
138
            if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;}
138
            if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;}
139
        }
139
        }
140
    }
140
    }
141
    else /* 0 < value < 1 --> exponent10 < 0 */
141
    else /* 0 < value < 1 --> exponent10 < 0 */
142
    {
142
    {
143
        while(value < 1){
143
        while(value < 1){
144
            value=value*10;
144
            value=value*10;
145
            exponent10--;
145
            exponent10--;
146
            /* need to set a limit to number of while loops ! */
146
            /* need to set a limit to number of while loops ! */
147
            if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;}
147
            if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;}
148
        }
148
        }
149
    }
149
    }
150
    /* 27/9/2013 avoid truncating and do rounding...but not with 7 significant digits*/
150
    /* 27/9/2013 avoid truncating and do rounding...but not with 7 significant digits*/
151
    if(sig > 6){factor = 100000;}else{factor = pow(10,sig+1);}
151
    if(sig > 6){factor = 100000;}else{factor = pow(10,sig+1);}
152
    value = (round(factor*value + (pm) ))/factor; /* pm = +/- 0.5 */
152
    value = (round(factor*value + (pm) ))/factor; /* pm = +/- 0.5 */
153
    if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){
153
    if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){
154
        format = 1; /* not in my list of prefixes ; print in html ! */
154
        format = 1; /* not in my list of prefixes ; print in html ! */
155
    }
155
    }
156
    sig = sig - 1; /* "%.*f" counts the "." */
156
    sig = sig - 1; /* "%.*f" counts the "." */
157
    if(cnt > 1){fprintf(stdout,",");}/* more than one conversion to do : make list */
157
    if(cnt > 1){fprintf(stdout,",");}/* more than one conversion to do : make list */
158
    int idx=0;int exp=0;
158
    int idx=0;int exp=0;
159
    if(exponent10 == 0){format = 6;} /* no need for 2*10^0 */
159
    if(exponent10 == 0){format = 6;} /* no need for 2*10^0 */
160
    if(sig < 0){sig = 0;} /* better be safe than sorry... */
160
    if(sig < 0){sig = 0;} /* better be safe than sorry... */
161
    switch(format){
161
    switch(format){
162
        case 0: fprintf(stdout, "%s%.*f*10^%d", sign, sig, value, exponent10);break;
162
        case 0: fprintf(stdout, "%s%.*f*10^%d", sign, sig, value, exponent10);break;
163
        case 1: fprintf(stdout, "%s%.*f&times;10<sup>%d</sup>", sign, sig, value, exponent10);break;
163
        case 1: fprintf(stdout, "%s%.*f&times;10<sup>%d</sup>", sign, sig, value, exponent10);break;
164
        case 2: fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig, value, exponent10);break;
164
        case 2: fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig, value, exponent10);break;
165
        case 3:
165
        case 3:
166
/*
166
/*
167
1,1,3 -> 1
167
1,1,3 -> 1
168
10,1,3 -> 1*10^-2 k
168
10,1,3 -> 1*10^-2 k
169
100,1,3 -> 1*10^-1 k
169
100,1,3 -> 1*10^-1 k
170
1000,1,3 -> 1 k
170
1000,1,3 -> 1 k
Line 183... Line 183...
183
0.000001,1,3 -> 1 µ
183
0.000001,1,3 -> 1 µ
184
0.0000001,1,3-> 1*10^-1 µ
184
0.0000001,1,3-> 1*10^-1 µ
185
0.00000001,1,3-> 1*10^-2 µ
185
0.00000001,1,3-> 1*10^-2 µ
186
0.000000001,1,3-> 1 n
186
0.000000001,1,3-> 1 n
187
*/
187
*/
188
        exp = exponent10%3;
188
        exp = exponent10%3;
189
        idx = round(exponent10/3);
189
        idx = round(exponent10/3);
190
        if( exponent10 > 0  ){
190
        if( exponent10 > 0  ){
191
            if(use_word == 0 ){ prefix = plus[idx]; } else { prefix = plus_word[idx]; }
191
            if(use_word == 0 ){ prefix = plus[idx]; } else { prefix = plus_word[idx]; }
192
        }
192
        }
193
        else
193
        else
194
        {
194
        {
195
            if(use_word == 0){ prefix = min[-1*idx]; } else { prefix = min_word[-1*idx]; }
195
            if(use_word == 0){ prefix = min[-1*idx]; } else { prefix = min_word[-1*idx]; }
196
        }
196
        }
197
        if( exp == 0){
197
        if( exp == 0){
198
            fprintf(stdout, "%s%.*f %s",sign, sig, value,prefix);
198
            fprintf(stdout, "%s%.*f %s",sign, sig, value,prefix);
199
        }
199
        }
200
        else
200
        else
201
        {
201
        {
202
            fprintf(stdout, "%s%.*f&times;10<sup>%d</sup> %s", sign, sig, value, exp, prefix);
202
            fprintf(stdout, "%s%.*f&times;10<sup>%d</sup> %s", sign, sig, value, exp, prefix);
203
        }
203
        }
204
        break;
204
        break;
205
        case 4: fprintf(stdout, "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mstyle id=\"wims_mathml\" mathsize=\"110%%\"><mn>%s%.*f</mn><mo>&times;</mo><msup><mn>10</mn><mn>%d</mn></msup></mstyle></math>", sign, sig, value, exponent10);break;
205
        case 4: fprintf(stdout, "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mstyle id=\"wims_mathml\" mathsize=\"110%%\"><mn>%s%.*f</mn><mo>&times;</mo><msup><mn>10</mn><mn>%d</mn></msup></mstyle></math>", sign, sig, value, exponent10);break;
206
        case 5: break;
206
        case 5: break;
207
        case 6: fprintf(stdout, "%s%.*f",sign,sig,value);break;
207
        case 6: fprintf(stdout, "%s%.*f",sign,sig,value);break;
208
        default: break;
208
        default: break;
209
    }
209
    }
210
    return NULL;
210
    return NULL;
211
}
211
}
212
 
212
 
213
int main( int argc , char *argv[]){
213
int main( int argc , char *argv[]){
214
 
214
 
215
    if( argc < 2){
215
    if( argc < 2){
216
        fprintf(stdout,"syntax error : number1,significance1,type1 number2,significance2,type2 ... number_n,significance_n,type_n \n");
216
        fprintf(stdout,"syntax error : number1,significance1,type1 number2,significance2,type2 ... number_n,significance_n,type_n \n");
217
        return 0;
217
        return 0;
218
    }
218
    }
219
 
219
 
220
    double number = 0;
220
    double number = 0;
221
    int significance = 0,type = 0,idx = 0,cnt = 1,size = 0;
221
    int significance = 0,type = 0,idx = 0,cnt = 1,size = 0;
222
    char *input = "\0",*ptr = "\0";
222
    char *input = "\0",*ptr = "\0";
Line 226... Line 226...
226
    /* Ee +- are allowed : 12.34e+05  12.34e-08 */
226
    /* Ee +- are allowed : 12.34e+05  12.34e-08 */
227
 
227
 
228
    /* walk through argument 1 to end, and call function scienceprint(a,b,c) */
228
    /* walk through argument 1 to end, and call function scienceprint(a,b,c) */
229
    input = argv[cnt];
229
    input = argv[cnt];
230
    while( input != NULL ){
230
    while( input != NULL ){
231
        if(cnt > MAX_CONV){fprintf(stdout,"\nerror: number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
231
        if(cnt > MAX_CONV){fprintf(stdout,"\nerror: number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
232
        while (*input){ /* loop through invalid chars. */
232
        while (*input){ /* loop through invalid chars. */
233
            if ( strchr(invalid_characters, *input) ){
233
            if ( strchr(invalid_characters, *input) ){
234
                fprintf(stdout,"\nerror : illegal character \"%s\" \n",input);
234
                fprintf(stdout,"\nerror : illegal character \"%s\" \n",input);
235
                return 0;
235
                return 0;
236
            }
236
            }
237
            input++;
237
            input++;
238
        }
238
        }
239
        /* reset input to actual value */
239
        /* reset input to actual value */
240
        input = argv[cnt];
240
        input = argv[cnt];
241
        ptr = (char *) strtok(input,",");
241
        ptr = (char *) strtok(input,",");
242
        idx = 0;
242
        idx = 0;
243
        type = 0;
243
        type = 0;
244
        size = 0;
244
        size = 0;
245
        while( ptr != NULL ){
245
        while( ptr != NULL ){
246
            switch( idx ){
246
            switch( idx ){
247
                case 0:
247
                case 0:
248
                        /* size only interesting when 'significance=-1'
248
                        /* size only interesting when 'significance=-1'
249
                         determine number of digits : 1.23445e+23 -> size = 6
249
                         determine number of digits : 1.23445e+23 -> size = 6
250
                        */
250
                        */
251
                        size = strlen(ptr);
251
                        size = strlen(ptr);
252
                        if( strstr(ptr,".") != NULL){size = size - 1 ;}
252
                        if( strstr(ptr,".") != NULL){size = size - 1 ;}
253
                        if( strstr(ptr,"*10^") != NULL){
253
                        if( strstr(ptr,"*10^") != NULL){
254
                            ptr = str_replace(ptr,"*10^","E");
254
                            ptr = str_replace(ptr,"*10^","E");
255
                            if(ptr == NULL){
255
                            if(ptr == NULL){
256
                                fprintf(stdout,"error : in replacement of 10^ notation\n");
256
                                fprintf(stdout,"error : in replacement of 10^ notation\n");
257
                                return 0;
257
                                return 0;
258
                            }
258
                            }
259
                            size = size - 3;
259
                            size = size - 3;
260
                        }
260
                        }
261
                        if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));}
261
                        if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));}
262
                        if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));}
262
                        if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));}
263
                        number = atof(ptr);
263
                        number = atof(ptr);
264
                        break;
264
                        break;
265
                case 1: significance = atoi(ptr);  break;
265
                case 1: significance = atoi(ptr);  break;
266
                case 2: type = atoi(ptr); if(type < 0 || type > 5 ){type = 0;} break;
266
                case 2: type = atoi(ptr); if(type < 0 || type > 5 ){type = 0;} break;
267
                default: break;
267
                default: break;
268
            }
268
            }
269
            idx++;
269
            idx++;
270
            ptr = (char *) strtok(NULL,",");
270
            ptr = (char *) strtok(NULL,",");
271
        }
271
        }
272
        /* number and precision are mandatory:  default type=0  */
272
        /* number and precision are mandatory:  default type=0  */
273
        if( idx < 2 || idx > 3){fprintf(stdout,"\nsyntax error : number1,significance1,type1 number2,significance2,type2 ... number_n,significance_n,type_n \n");return 0;}
273
        if( idx < 2 || idx > 3){fprintf(stdout,"\nsyntax error : number1,significance1,type1 number2,significance2,type2 ... number_n,significance_n,type_n \n");return 0;}
274
        /* call conversion routine */
274
        /* call conversion routine */
275
        printscience(number, significance, type , cnt , size);
275
        printscience(number, significance, type , cnt , size);
276
        cnt++;
276
        cnt++;
277
        input = argv[cnt];
277
        input = argv[cnt];
278
    }
278
    }
279
    fprintf(stdout,"\n");
279
    fprintf(stdout,"\n");
280
    return 0;
280
    return 0;
281
}
281
}
282
 
282