Subversion Repositories wimsdev

Rev

Rev 5213 | 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.  
  10.  
  11. usage:
  12. 1) discard trailing zeros : use no flags (default)
  13. !exec sigdigits 1.10000 2.0001000 123.0100010000
  14. 2,1  
  15. 5,4  
  16. 9,6
  17.  
  18. or use flag "0"
  19. !exec sigdigits 1.10000,0 2.0001000,0 123.0100010000,0
  20. 2,1  
  21. 5,4  
  22. 9,6
  23.  
  24. 2) include trailing zeros : use flag "1" (due to accuracy measurement...)
  25. !exec sigdigits 1.10000,1 2.0001000,1 123.0100010000,1
  26. 7,5
  27. 9,7
  28. 14,10
  29.  
  30. 3) scientific notation allowed:
  31. !exec sigdigits 1.2300000*10^15
  32. 3,2
  33. !exec sigdigits 1.2300001*10^15
  34. 8,7
  35. !exec sigdigits 1.2300000e+15
  36. 3,2
  37. !exec sigdigits 1.2300001e+15
  38. 8,7
  39.  
  40. 4) all other 'numbers' using pi,log,ln,sin,etc...will produce an error
  41.  
  42. 5)output "2 items per line"
  43.     first item is total amount of significant digits
  44.     second item is amount of decimals
  45.  
  46. 6) no evaluation on the 'size' of the number is performed.
  47.  
  48. It can be used in an answer checkfile,
  49. to check if the pupil uses the correct amount of significant digits in the reply .
  50. Example:
  51. A circle with "R=2.01 cm" has a surface area of ?
  52. The 'math' answer is approx 12.69234847976812366271292553 cm2
  53. The 'physics' answer is 12.7 ... using 3 significant digits
  54. (due to the precision of the given R. note: there is no checking of the unit 'cm')
  55.  
  56.  
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <string.h>
  61. #define MAX_DIGITS 64
  62. #define MAX_CONV 64
  63.  
  64.  
  65. int main( int argc , char *argv[]){
  66.     if( argc < 2){
  67.         fprintf(stdout,"syntax error\n");
  68.         exit(0);
  69.     }
  70.     char word[MAX_DIGITS];
  71.     char *input;
  72.     int use_all_zeros,cnt,i,length,zeros,significance,found_digit,found_point,decimals;
  73.     const char *invalid_characters = "\n\"\'!=ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz@#$%&()[]{};:~><?/\\|";
  74.     /* Ee +- are allowed : 12.34e+05  12.34e-08  1.234*10^123*/
  75.     cnt = 1;
  76.     input = argv[cnt];
  77.     while( input != NULL){
  78.         if(cnt > MAX_CONV){fprintf(stdout,"error : number of conversions exceeds limit of %d\n",MAX_CONV);return 0;}
  79.         length = strlen(input);
  80.         if( length > MAX_DIGITS){                                                                                                          
  81.             fprintf(stdout,"error : number is larger than %d digits\n",MAX_DIGITS);                                                            
  82.             exit(0);                                                                                                                      
  83.         }
  84.         /* test for illegal characters */
  85.         while (*input){
  86.             if ( strchr(invalid_characters, *input) ){
  87.                 fprintf(stdout,"error : found illegal character in argument \"%s\" \n",input);
  88.                 return 0;
  89.             }
  90.             input++;
  91.         }
  92.         input = argv[cnt];
  93.         strncpy( word, input, length );
  94.         // reset
  95.         found_digit = 0;
  96.         found_point = 0;
  97.         decimals = 0;
  98.         significance = 0;
  99.         zeros = 0;
  100.         use_all_zeros = 0; // trailing zeros are not significant...unless
  101.         for( i = length - 1 ; i >= 0 ; i--){ // walk from rightside to left through the 'number'
  102.             switch( word[i] ){
  103.                 case '*' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
  104.                 case 'e' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
  105.                 case 'E' : significance = 0;decimals = 0;found_digit = 0;zeros = 0;break;
  106.                 case ',' : // signaling a flag '1'
  107.                     if( i+1 < length ){
  108.                         if(word[i + 1] == '1'){ use_all_zeros = 1;}
  109.                     }
  110.                     significance = 0;
  111.                     decimals = 0;
  112.                     found_digit = 0;
  113.                     zeros = 0;
  114.                     break;
  115.                 case '0' :
  116.                     if(i == 0){//last char
  117.                         significance = significance - zeros;
  118.                     }
  119.                     else
  120.                     {
  121.                         if( found_digit == 1 ){
  122.                             significance++;
  123.                         }
  124.                         else
  125.                         {
  126.                             if( found_point == 0 && use_all_zeros == 1){
  127.                                 significance++;
  128.                             }
  129.                         }
  130.                         zeros++;
  131.                     }
  132.                     break;
  133.                 case '.' : decimals = significance; found_point = 1; break;
  134.                 case '1' : significance++;found_digit = 1;zeros = 0; break;
  135.                 case '2' : significance++;found_digit = 1;zeros = 0; break;
  136.                 case '3' : significance++;found_digit = 1;zeros = 0; break;
  137.                 case '4' : significance++;found_digit = 1;zeros = 0; break;
  138.                 case '5' : significance++;found_digit = 1;zeros = 0; break;
  139.                 case '6' : significance++;found_digit = 1;zeros = 0; break;
  140.                 case '7' : significance++;found_digit = 1;zeros = 0; break;
  141.                 case '8' : significance++;found_digit = 1;zeros = 0; break;
  142.                 case '9' : significance++;found_digit = 1;zeros = 0; break;
  143.                 default :  break;
  144.             }
  145.         }
  146.         cnt++;
  147.         input = argv[cnt];
  148.         fprintf(stdout,"%d,%d\n",significance,decimals);
  149.     }
  150.     return (0);
  151. }
  152.