Subversion Repositories wimsdev

Rev

Rev 5207 | Rev 5219 | 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. syntax number_1 number2 number_3 ... number_n
  10.  
  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
  16.  
  17. result is
  18. 1 line per input number
  19. 6 items per line:
  20.  
  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)
  23.  
  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)
  27.  
  28. item 5) exponent (if not present : 0)
  29.  
  30. item 6) indication : is the number correctly written ?  1 or 0  ( 000.1 is not correct...)
  31.  
  32. exponent '10^' or 'e': 1.23*10^-4 1.23e-4
  33. */
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #define MAX_DIGITS 64
  39. #define MAX_CONV 64
  40.  
  41. void append(char* s, char c){
  42.     int len = strlen(s);
  43.     s[len] = c;
  44.     s[len+1] = '\0';
  45. }
  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;
  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;
  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;
  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';
  89.         for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
  90.             switch( word[i] ){
  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;
  95.                 case '0' :
  96.                     if(i == 0){//last char
  97.                         sig1 = sig1 - zeros;
  98.                         sig2++;
  99.                     }
  100.                     else
  101.                     {
  102.                         if( found_point == 1 ){ sig2++; }
  103.                         if( found_digit == 1 ){ sig1++; }
  104.                         zeros++;
  105.                     }
  106.                     break;
  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;
  117.                 default :  break;
  118.             }
  119.            
  120.             if(found_power == 0){ append(exp,word[i]); } // maybe a power was used ?
  121.         }
  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.         }
  148.         cnt++;
  149.         input = argv[cnt];
  150.     }
  151.     return (0);
  152. }
  153.