Subversion Repositories wimsdev

Rev

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

  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. 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
  13.  
  14. 2/2012
  15.  modified for general rounding usage; a word 'DECIMALS' can be added to the list of numbers
  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  
  22.  
  23. 6/2012.
  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
  27.  
  28.  assumed only powers of 10 [scientific notation]
  29.  
  30. 12/2012
  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')
  34.  
  35. 27/2014
  36. Modified avoiding truncating of numbers like 15.625 --> 16.62
  37.  
  38. */
  39.  
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <math.h>
  44. #define MAX_DIGITS 32
  45. #define MAX_CONV 32
  46.  
  47. int main( int argc , char *argv[]){
  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.                     }
  131.                 }
  132.                 else
  133.                 {
  134.                     if(powE > 0){
  135.                         exponent[idx2] = word[i];
  136.                         idx2++;
  137.                     }
  138.                     else
  139.                     {
  140.                         number[idx1] = word[i];
  141.                         idx1++;
  142.                     }
  143.                 }
  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;
  181. }
  182.  
  183.