Subversion Repositories wimsdev

Rev

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

Rev 5950 Rev 6738
Line 5... Line 5...
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
-
 
11
Corrected significance flaw when using prefixes
-
 
12
Simplified routines
-
 
13
Added type = 5 : prefix-notation with words (nano,mega,giga...etc)
10
 
14
 
11
12/11/2012
15
12/11/2012
12
Added support for numbers like  12345*10^12
16
Added support for numbers like  12345*10^12
13
12345*10^12 --> 12345E12 ---> 1.2345*10^16
17
12345*10^12 --> 12345E12 ---> 1.2345*10^16
14
 
18
 
Line 45... Line 49...
45
15  peta        P
49
15  peta        P
46
12  tera        T
50
12  tera        T
47
9   giga        G
51
9   giga        G
48
6   mega        M
52
6   mega        M
49
3   kilo        k
53
3   kilo        k
-
 
54
 
50
2   hecto       h
55
2   hecto       h
51
1   deca        da
56
1   deca        da
52
-1  deci        d
57
-1  deci        d
53
-2  centi       c
58
-2  centi       c
-
 
59
 
54
-3  milli       m
60
-3  milli       m
55
-6  micro       µ
61
-6  micro       µ
56
-9  nano        n
62
-9  nano        n
57
-12 pico        p
63
-12 pico        p
58
-15 femto       f
64
-15 femto       f
Line 65... Line 71...
65
#include <stdio.h>
71
#include <stdio.h>
66
#include <math.h>
72
#include <math.h>
67
#include <string.h>
73
#include <string.h>
68
#include <stdlib.h>
74
#include <stdlib.h>
69
#define MICRO "µ"
75
#define MICRO "µ"
70
#define PREFIX_START (-24)
-
 
71
#define PREFIX_END 24
-
 
72
#define MAX_CONV 256
76
#define MAX_CONV 256
73
#define MAX_STRING 32
77
#define MAX_STRING 32
-
 
78
#define PREFIX_START -24
-
 
79
#define PREFIX_END 24
74
 
80
 
75
char *str_replace ( const char *word, const char *sub_word, const  char *rep_word ){
81
char *str_replace ( const char *word, const char *sub_word, const  char *rep_word ){
76
    if(strlen(word) > MAX_STRING){return NULL;}
82
    if(strlen(word) > MAX_STRING){return NULL;}
77
    char *part_word = NULL;
83
    char *part_word = NULL;
78
    char *new_word = NULL;
84
    char *new_word = NULL;
Line 99... Line 105...
99
    }
105
    }
100
    return new_word;
106
    return new_word;
101
}
107
}
102
 
108
 
103
char *printscience(double value, int sig, int format , int cnt ,int size){
109
char *printscience(double value, int sig, int format , int cnt ,int size){
-
 
110
    static char *min[] = {"","m",MICRO,"n","p","f","a","z","y"};
104
    static char *prefix[] = { "y", "z", "a", "f", "p", "n", MICRO, "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" };
111
    static char *plus[] = {"","k", "M", "G", "T", "P", "E", "Z", "Y" };
-
 
112
    static char *min_word[] = {"","milli","micro","nano","pico","femto","atto","zepto","yocto"};
105
    double display, fract;
113
    static char *plus_word[] = {"","kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta" };
106
    char *sign = NULL;
114
    char *sign = NULL;char *prefix = NULL;
107
    int exponent10;
115
    int exponent10 = 0;
-
 
116
    int use_word = 0;if(format == 5){format = 3; use_word = 1;} /* switch to using words in stead of prefix  */
-
 
117
    if(value < 0.0) {sign = "-";value = -value;sig--;} else {sign = "";}    if( sig == -1 ){
108
    if( sig == -1 ){
118
     /*
109
     /* no significance truncations...just science notation 1234 -> 1.234*10^3  ; try (!) to use same amount of digits*/
119
     no significance truncations...just science notation 1234 -> 1.234*10^3
-
 
120
     try (!) to use same amount of digits
-
 
121
     */
110
        sig = size;
122
        sig = size;
111
        if(format == 3){format = 1;} /* no prefix --> html noation */
123
        if(format == 3){format = 1;} /* never prefix --> html notation */
112
        if(value < 0.0) {sign = "-";value = -value;sig--;} else {sign = "";}
-
 
113
        exponent10=0;
-
 
114
        if(value>=1){
-
 
115
            while(value > 10){
-
 
116
                value=value / 10.0;
-
 
117
                exponent10++;
-
 
118
                /* need to set a limit to number of while loops ! */
-
 
119
                if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;}
-
 
120
            }
-
 
121
        }
-
 
122
        else /* 0 < value < 1 --> exponent10 < 0 */
-
 
123
        {
-
 
124
            while(value < 1){
-
 
125
                value=value*10;
-
 
126
                exponent10--;
-
 
127
                /* need to set a limit to number of while loops ! */
-
 
128
                if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;}
-
 
129
            }
-
 
130
        }
-
 
131
    }
124
    }
132
    else
-
 
133
    {
-
 
134
        if(value < 0.0) {sign = "-";value = -value;} else {sign = "";}
-
 
135
        exponent10 = lrint( floor( log10(value) ) );/* correctly round to desired precision */
125
    if(value == 0){fprintf(stdout, "%s%.*f", sign, sig-1, value);return NULL;} /* no need to go further */
136
        value *= pow(10.0, sig - 1 - exponent10);
-
 
137
        fract = modf(value, &display);
-
 
138
        if(fract >= 0.5){display += 1.0;}
-
 
139
        value = display * pow(10.0, exponent10 - sig + 1);
-
 
140
        if(exponent10 > 0){exponent10 = (exponent10/3)*3;}else{exponent10 = ((-exponent10+3)/3)*(-3);}
-
 
141
        value *= pow(10.0, -exponent10);
-
 
142
        if(format != 3){ /* allow all powers; not limited by prefix list */
-
 
143
            if(value > 10.0){
126
    if(value>1){
144
                while(value >= 10){
127
        while(value >= 10){
145
                    value = value / 10.0;
128
            value=value / 10.0;
146
                    exponent10++;
129
            exponent10++;
147
                    /* need to set a limit to number of while loops ! */
130
            /* need to set a limit to number of while loops ! */
148
                    if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;}
131
            if(exponent10 > 100){fprintf(stdout,"error : number too big (exponent > 100)\n");return 0;}
149
                }
-
 
150
            }
-
 
151
        }
-
 
152
        else /* steps of powers dividable by 3 used for prefix notation */
-
 
153
        {
-
 
154
            if (value >= 1000.0) {
-
 
155
                value = value / 1000.0;
-
 
156
                exponent10 = exponent10 + 3;
-
 
157
            }
-
 
158
            else
-
 
159
            {
-
 
160
                if(value >= 100.0){
-
 
161
                    sig =  sig - 2;
-
 
162
                }
-
 
163
                else
-
 
164
                {
-
 
165
                    if(value >= 10.0){
-
 
166
                        sig = sig - 1;
-
 
167
                    }
-
 
168
                }
-
 
169
            }
-
 
170
        }
132
        }
171
    }
133
    }
172
    if(cnt > 1){fprintf(stdout,",");}
-
 
173
    /* check on format style versus exponent */
134
    else /* 0 < value < 1 --> exponent10 < 0 */
174
    if(exponent10 == 0 ){
-
 
175
        format = 3; /* do not use 1.23*10^0 */
-
 
176
    }
-
 
177
    else
-
 
178
    {
135
    {
179
        if(exponent10 == 1){
136
        while(value < 1){
180
            format = 3;/* do not use 1.23*10^1 */
-
 
181
            value = value * 10;
137
            value=value*10;
182
            sig = sig - 1;
138
            exponent10--;
-
 
139
            /* need to set a limit to number of while loops ! */
-
 
140
            if(exponent10 <-100){fprintf(stdout,"error : number too small (exponent < -100)\n");return 0;}
183
        }
141
        }
184
        else
-
 
185
        {
-
 
186
            if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){
-
 
187
                format = 1; /* if no prefix available, revert to html presentation */
-
 
188
            }
-
 
189
        }
-
 
190
   
-
 
191
    }
142
    }
-
 
143
    if(format == 3 && ((exponent10 < PREFIX_START) || (exponent10 > PREFIX_END))){
-
 
144
        format = 1; /* not in my list of prefixes ; print in html ! */
-
 
145
    }
-
 
146
    sig = sig - 1; /* "%.*f" counts the "." */
-
 
147
    if(cnt > 1){fprintf(stdout,",");}/* more than one conversion to do : make list */
192
    if(sig < 1){sig = 1;}
148
    int idx=0;int exp=0;
-
 
149
    if(exponent10 == 0){format = 6;} /* no need for 2*10^0 */
-
 
150
    if(sig < 0){sig = 0;} /* better be safe than sorry... */
193
    if(format != 3 ){
151
    switch(format){
-
 
152
        case 0: fprintf(stdout, "%s%.*f*10^%d", sign, sig, value, exponent10);break;
-
 
153
        case 1: fprintf(stdout, "%s%.*f&times;10<sup>%d</sup>", sign, sig, value, exponent10);break;
-
 
154
        case 2: fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig, value, exponent10);break;
-
 
155
        case 3:
-
 
156
/*
-
 
157
1,1,3 -> 1
-
 
158
10,1,3 -> 1*10^-2 k
-
 
159
100,1,3 -> 1*10^-1 k
-
 
160
1000,1,3 -> 1 k
-
 
161
10000,1,3 -> 1*10^1 k
-
 
162
100000,1,3 -> 1*10^2 k
-
 
163
1000000,1,3 -> 1 M
-
 
164
10000000,1,3 -> 1*10^1 M
-
 
165
100000000,1,3 -> 1*10^2 M
-
 
166
1000000000,1,3 -> 1 G
-
 
167
1,1,3 -> 1
-
 
168
0.1,1,3 -> 1*10^-1
-
 
169
0.01,1,3 -> 1*10^-2
-
 
170
0.001,1,3 -> 1 m
-
 
171
0.0001,1,3 -> 1*10^-1 m
-
 
172
0.00001,1,3 -> 1*10^-2 m
-
 
173
0.000001,1,3 -> 1 µ
-
 
174
0.0000001,1,3-> 1*10^-1 µ
-
 
175
0.00000001,1,3-> 1*10^-2 µ
-
 
176
0.000000001,1,3-> 1 n
-
 
177
*/
-
 
178
        exp = exponent10%3;
-
 
179
        idx = round(exponent10/3);
-
 
180
        if( exponent10 > 0  ){
194
        if( format == 0){ /* 'calculable' presentation */
181
            if(use_word == 0 ){ prefix = plus[idx]; } else { prefix = plus_word[idx]; }
-
 
182
        }
-
 
183
        else
-
 
184
        {
-
 
185
            if(use_word == 0){ prefix = min[-1*idx]; } else { prefix = min_word[-1*idx]; }
-
 
186
        }
-
 
187
        if( exp == 0){
195
            fprintf(stdout, "%s%.*f*10^%d", sign, sig-1, value, exponent10);
188
            fprintf(stdout, "%s%.*f %s",sign, sig, value,prefix);
196
        }
189
        }
197
        else
190
        else
198
        {
191
        {
199
            if( format == 1 ){ /* html presentation */
-
 
200
                fprintf(stdout, "%s%.*f&times;10<sup>%d</sup>", sign, sig-1, value, exponent10);
-
 
201
            }
-
 
202
            else
-
 
203
            {
-
 
204
                if(format == 2 ){/* latex presentation */
-
 
205
                    fprintf(stdout, "%s%.*f \\times 10^{%d}", sign, sig-1, value, exponent10);
-
 
206
                }
-
 
207
                else
-
 
208
                { /* mathml presentation */
-
 
209
                    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-1, value, exponent10);
192
            fprintf(stdout, "%s%.*f&times;10<sup>%d</sup> %s", sign, sig, value, exp, prefix);
210
                }
-
 
211
            }
-
 
212
        }
193
        }
213
    }
194
        break;
214
    else /* format = 3 : prefix presentation or other more suitable presentation */
195
        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;
215
    {
196
        case 5: break;
216
        fprintf(stdout, "%s%.*f %s", sign, sig-1, value,prefix[(exponent10-PREFIX_START)/3]);
197
        case 6: fprintf(stdout, "%s%.*f",sign,sig,value);break;
-
 
198
        default: break;
217
    }
199
    }
218
    return NULL;
200
    return NULL;
219
}
201
}
220
 
202
 
221
int main( int argc , char *argv[]){
203
int main( int argc , char *argv[]){
Line 269... Line 251...
269
                        if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));}
251
                        if( strstr(ptr,"E") != NULL){size = size - strlen(strstr(ptr,"E"));}
270
                        if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));}
252
                        if( strstr(ptr,"e") != NULL){size = size - strlen(strstr(ptr,"e"));}
271
                        number = atof(ptr);
253
                        number = atof(ptr);
272
                        break;
254
                        break;
273
                case 1: significance = atoi(ptr);  break;
255
                case 1: significance = atoi(ptr);  break;
274
                case 2: type = atoi(ptr); if(type < 0 || type > 4 ){type = 0;} break;
256
                case 2: type = atoi(ptr); if(type < 0 || type > 5 ){type = 0;} break;
275
                default: break;
257
                default: break;
276
            }
258
            }
277
            idx++;
259
            idx++;
278
            ptr = (char *) strtok(NULL,",");
260
            ptr = (char *) strtok(NULL,",");
279
        }
261
        }