Subversion Repositories wimsdev

Rev

Rev 13927 | Rev 14856 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3519 schaersvoo 1
/*
2
*********************************************************************************
13932 schaersvoo 3
* J.M. Evers 3/2012                                                             *
3519 schaersvoo 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 *
5416 schaersvoo 7
* No warrenty whatsoever                                                        *
3519 schaersvoo 8
*********************************************************************************
13932 schaersvoo 9
general use:
10
rounding to 2 decimals (financial math)
11
tot=!exec moneyprint 0.1,17,123.4,123.99765
12
tot -> 0.10,17.00,123.40,124.00
5416 schaersvoo 13
 
5154 schaersvoo 14
2/2012
15
 modified for general rounding usage; a word 'DECIMALS' can be added to the list of numbers
5416 schaersvoo 16
 tot=!exec moneyprint 2.1,4.123,5  2   // 2 decimals
17
 tot -> 2.10,4.12,5.00
18
 tot=!exec moneyprint 2.1,4.123,5  4   // 4 decimals
19
 tot -> 2.1000,4.1230,5.0000
20
 tot=!exec moneyprint 2.1,4.123,5
21
 tot -> 2.10,4.12,5.00 //default value (or old syntax) is 2 decimals  
5154 schaersvoo 22
 
13932 schaersvoo 23
6/2012.
5416 schaersvoo 24
 modified again to support rounding of scientific numbers, like
25
 tot=!exec moneyprint 1.23456e+06,1.23456*10^6,0.01234e-23 3
26
 tot -> 1.235e06,1.235e6,0.012e-23
13932 schaersvoo 27
 
5416 schaersvoo 28
 assumed only powers of 10 [scientific notation]
29
 
6273 schaersvoo 30
12/2012
13932 schaersvoo 31
Modified : using only 10^ in powers
32
(e+8 -> *10^8 ; e-8 -> *10^-8)
33
Extra syntax error signal (using more than 1 'e')
6273 schaersvoo 34
 
8346 schaersvoo 35
27/2014
13932 schaersvoo 36
Modified avoiding truncating of numbers like 15.625 --> 16.62
8346 schaersvoo 37
 
3519 schaersvoo 38
*/
8346 schaersvoo 39
 
3519 schaersvoo 40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <string.h>
8346 schaersvoo 43
#include <math.h>
13932 schaersvoo 44
#define MAX_DIGITS 32
5416 schaersvoo 45
#define MAX_CONV 32
3519 schaersvoo 46
 
3689 schaersvoo 47
int main( int argc , char *argv[]){
13932 schaersvoo 48
    if( argc != 2 && argc != 3){
49
        fprintf(stdout,"error !\nusage:\n!exec moneyprint $your_wims_item_list $precision_word\nexample:\nmoney=!exec moneyprint 1.2,30.1,.4,-.23123456 2\nThe result is a comma separated list: 1.20,30.10,0.40,-0.23\n using 2 decimals\nNote: no calculations are done.\nNo spaces allowed \n");
50
        exit(0);
51
    }
52
    /* test for illegal characters */
53
    const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWYZabcdfghijklmnopqrstuvwyz@#$%&()[]{};:~><?/\\|";
54
    /* +-*^XxEe are allowed : 12.34e+05  12.34e-08 1x10^5 1.234*10^123*/
55
    char *input;
56
    input = argv[1];
57
    while (*input){
58
        if ( strchr(invalid_characters, *input) ){
59
            fprintf(stdout,"error !\nfound illegal character \"%c\" in argument\n",*input);
60
            exit(0);
61
        }
62
        input++;
63
    }
64
    int DECIMALS;
65
    if(argv[2] != NULL){
66
        DECIMALS = atoi(argv[2]);
67
        if(DECIMALS > MAX_DIGITS){
68
            fprintf(stdout,"error ! maximum amount of decimals is %d \n",MAX_DIGITS);exit(0);
69
        }
70
    }
71
    else
72
    {
73
        DECIMALS = 2;
74
    }
75
    char *ptr;
76
    char word[MAX_DIGITS];
77
    char exponent[MAX_DIGITS];
78
    char number[MAX_DIGITS];
79
    int cnt = 1;
80
    int powE = 0;
81
    int idx1 = 0;
82
    int idx2 = 0;
83
    int length= 0;
84
    int i = 0;
85
    int pow10 = 0;
86
    double correction = 1/(pow(10,DECIMALS+6)); /* a reasonable guess...to avoid truncating 15.625 --> 16.63 */
87
    double ascii_number;
88
    input = argv[1];
89
    ptr = strtok(input,",");
90
    while( ptr != NULL){
91
        if(  cnt > MAX_CONV ){
92
            fprintf(stdout,"ERROR too many (> %d)conversion \n",MAX_CONV);
93
            exit(0);
94
        }
95
        // next item in input argv[1]
96
        strncpy( word, ptr, MAX_DIGITS);
97
        length = strlen(ptr);
98
        if(length > MAX_DIGITS-1){
99
            fprintf(stdout,"ERROR string too large\n");
100
            exit(0);
101
        }
102
        //reset counters
103
        powE = 0;
104
        pow10 = 0;
105
        idx1 = 0;
106
        idx2 = 0;
107
        i = 0;
108
        for( i = 0; i < length ; i++){
109
            if(powE > 1 ){
110
                fprintf(stdout,"ERROR in syntax\n");
111
                exit(0);
112
            }
113
            if( idx1 + idx2  >  MAX_DIGITS-1){
114
                fprintf(stdout,"ERROR string too large\n");
115
                exit(0);
116
            }
117
            switch( word[i] ){
118
                case '+' : break; /* do not use 10^+2 */
119
                case 'e' : powE++;break;
120
                case 'E' : powE++;break;
121
                case 'x' : pow10++;break;
122
                case '*' : pow10++;break;
123
                case '^' : pow10=5;break;
124
                default  :
125
                if( pow10 > 0 ){
126
                    pow10++;
127
                    if( pow10 > 4 ){ /*  *10^ = 4 chars */
128
                        exponent[idx2] = word[i];
129
                        idx2++;
130
                    }
5416 schaersvoo 131
                }
132
                else
13932 schaersvoo 133
                {
134
                    if(powE > 0){
135
                        exponent[idx2] = word[i];
136
                        idx2++;
137
                    }
138
                    else
139
                    {
140
                        number[idx1] = word[i];
141
                        idx1++;
142
                    }
5416 schaersvoo 143
                }
13932 schaersvoo 144
                break;
145
            }
146
        }
147
        exponent[idx2] = '\0';
148
        number[idx1] = '\0';
149
        ascii_number = atof(number);
150
        if( ascii_number > 0 ){
151
            ascii_number = ascii_number + correction;
152
        }
153
        else
154
        {
155
            ascii_number = ascii_number - correction;
156
        }
157
        if( powE == 1 || pow10> 0 ){
158
            if(cnt > 1){
159
                fprintf( stdout , ",%.*f*10^%s" , DECIMALS , ascii_number , exponent );
160
            }
161
            else
162
            {
163
                fprintf( stdout , "%.*f*10^%s" , DECIMALS , ascii_number , exponent );
164
            }
165
        }
166
        else
167
        {
168
            if(cnt > 1 ){
169
                fprintf( stdout , ",%.*f" , DECIMALS , ascii_number);  
170
            }
171
            else
172
            {
173
                fprintf( stdout , "%.*f" , DECIMALS , ascii_number);   
174
            }
175
        }
176
        cnt++;
177
        ptr = strtok(NULL,",");
178
    }
179
    fprintf(stdout,"\n");
180
    return 0;
3519 schaersvoo 181
}
13932 schaersvoo 182