fork(1) download
  1. /** $ gcc -std=c99 *.c -lm && (echo ' (12 32(32 12))' | ./a.out) */
  2. #include <errno.h>
  3. #include <inttypes.h> /* uintmax_t, PRIuMAX */
  4. #include <limits.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <stdlib.h> /* EXIT_FAILURE */
  8. #include <string.h>
  9.  
  10. int main(void) {
  11. long double sum = 0.0; /* result */
  12. uintmax_t position = 0, /* the current position in the input */
  13. depth = 0, /* how deep parens are nested */
  14. number = 0; /* the current number */
  15. int c;
  16. for ( ; (c = getchar()) != EOF; ++position) {
  17. if ('0' <= c && c <= '9') {
  18. if (number > (UINTMAX_MAX - (c - '0')) / 10U) {
  19. fprintf(stderr, "error: input number is too large at (offset)%" PRIuMAX
  20. ", limit %" PRIuMAX "\n", position, UINTMAX_MAX);
  21. exit(EXIT_FAILURE);
  22. }
  23. number = 10*number + (c - '0');
  24. }
  25. else { /* not a digit */
  26. if (number) {
  27. /* result += a[i] * (0.5)**(b[i]) */
  28. errno = 0;
  29. sum += number * powl(.5, depth); /* number >> depth */
  30. if (errno) { /*NOTE: ignore `+*` math errors */
  31. fprintf(stderr, "error: powl: %s at (offset)%" PRIuMAX "\n",
  32. strerror(errno), position);
  33. exit(EXIT_FAILURE);
  34. }
  35. number = 0; /* reset number */
  36. }
  37.  
  38. if (c == '(')
  39. ++depth; /*NOTE: ignore the (unlikely) overflow */
  40. else if (c == ')') {
  41. if (depth == 0) {
  42. fprintf(stderr , "error: unexpected closing paren at "
  43. "(offset)%" PRIuMAX "\n", position);
  44. exit(EXIT_FAILURE);
  45. }
  46. --depth;
  47. }
  48. else if (c == '-') {
  49. fprintf(stderr, "error: minus sign at (offset)%" PRIuMAX
  50. " (program doesn't support negative numbers)\n", position);
  51. exit(EXIT_FAILURE);
  52. }
  53. }
  54. }
  55. if (printf("%Lf\n", sum) < 0)
  56. exit(EXIT_FAILURE);
  57. return feof(stdin) ? EXIT_SUCCESS : EXIT_FAILURE;
  58. }
Success #stdin #stdout 0s 2296KB
stdin
(3332 554)
stdout
1943.000000