wcalc  2.5
About: Wcalc is a natural-expression command-line calculator.
  Fossies Dox: wcalc-2.5.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

calculator.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #else
4 # define HAVE_MPFR_22
5 #endif
6 #include <stdlib.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <math.h> /* for HUGE_VAL */
10 #include <float.h> /* for DBL_EPSILON */
11 #include <ctype.h> /* for isalpha() */
12 #include <assert.h>
13 
14 #include "output.h"
15 
16 #ifndef isnan
17 # define isnan(x) \
18  (sizeof(x) == sizeof(long double) ? isnan_ld(x) \
19  : sizeof(x) == sizeof(double) ? isnan_d(x) \
20  : isnan_f(x))
21 static inline int
22 isnan_f(float x)
23 { /*{{{*/
24  return x != x;
25 } /*}}}*/
26 
27 static inline int
28 isnan_d(double x)
29 { /*{{{*/
30  return x != x;
31 } /*}}}*/
32 
33 static inline int
34 isnan_ld(long double x)
35 { /*{{{*/
36  return x != x;
37 } /*}}}*/
38 #endif /* ifndef isnan */
39 
40 #ifndef isinf
41 # define isinf(x) \
42  (sizeof(x) == sizeof(long double) ? isinf_ld(x) \
43  : sizeof(x) == sizeof(double) ? isinf_d(x) \
44  : isinf_f(x))
45 static inline int
46 isinf_f(float x)
47 { /*{{{*/
48  return isnan(x - x);
49 } /*}}}*/
50 
51 static inline int
52 isinf_d(double x)
53 { /*{{{*/
54  return isnan(x - x);
55 } /*}}}*/
56 
57 static inline int
58 isinf_ld(long double x)
59 { /*{{{*/
60  return isnan(x - x);
61 } /*}}}*/
62 #endif /* ifndef isinf */
63 
64 #if !defined(HAVE_CONFIG_H) || HAVE_STRING_H
65 # include <string.h> /* for memset() */
66 #else
67 # if !HAVE_STRCHR
68 # define strchr index
69 # define strrchr rindex
70 # endif
71 char *strchr(), *strrchr();
72 #endif
73 
74 #if !defined(HAVE_CONFIG_H) || TIME_WITH_SYS_TIME /* for time() */
75 # include <sys/time.h>
76 # include <time.h>
77 #else
78 # if HAVE_SYS_TIME_H
79 # include <sys/time.h>
80 # else
81 # include <time.h>
82 # endif
83 #endif
84 
85 #include "number.h"
86 
87 #include "uint32_max.h"
88 #include "calculator.h"
89 #include "variables.h"
90 #include "string_manip.h"
91 #include "files.h"
92 #include "number_formatting.h"
93 #include "add_commas.h"
94 #include "list.h"
95 #include "extract_vars.h"
96 
97 /* variables everyone needs to get to */
99 char *pretty_answer = NULL;
100 
101 /* communication with the parser */
102 char compute = 1;
103 unsigned int sig_figs = UINT32_MAX;
104 
105 /* communication with the frontend */
108 char *pa = NULL;
109 char *last_input = NULL;
110 
111 struct _conf conf;
112 
113 /*
114  * These are declared here because they're not in any header files.
115  * yyparse() is declared with an empty argument list so that it is
116  * compatible with the generated C code from yacc/bison.
117  * These two lines are taken from http://www.bgw.org/tutorials/programming/c/lex_yacc/main.c
118  */
119 struct yy_buffer_state;
120 extern int yyparse(void);
121 extern void *yy_scan_string(const char *);
122 extern void yy_delete_buffer(struct yy_buffer_state *);
123 
124 static int recursion(char *str);
125 static int find_recursion(char *);
126 static int find_recursion_core(List);
127 static char *flatten(char *str);
128 
129 void
130 parseme(const char *pthis)
131 { /*{{{ */
132  extern int synerrors;
133  short numbers = 0;
134  char *sanitized;
135  extern char *open_file;
136 
137  synerrors = 0;
138  compute = 1;
140 
141  Dprintf("parsing: %s\n", pthis);
142  sanitized = (char *)strdup(pthis);
143 
144  /* Save a copy of the input */
145  {
146  extern int show_line_numbers;
147 
148  if (show_line_numbers) {
149  if (last_input) {
150  free(last_input);
151  }
152  last_input = strdup(pthis);
153  }
154  }
155  /* Convert to standard notation (american comma and period) if there are
156  * numbers */
157  // are there numbers?
158  {
159  unsigned int i;
160 
161  for (i = 0; i < strlen(sanitized); ++i) {
162  if (isdigit((int)(sanitized[i]))) {
163  numbers = 1;
164  break;
165  }
166  }
167  }
168  if (numbers) {
169  unsigned int i;
170 
171  for (i = 0; i < strlen(sanitized); ++i) {
172  if (((conf.thou_delimiter != '.') && (conf.dec_delimiter != '.') &&
173  (conf.in_thou_delimiter != '.') && (conf.in_dec_delimiter != '.') &&
174  (sanitized[i] == '.')) || ((conf.thou_delimiter != ',') &&
175  (conf.in_thou_delimiter != ',') &&
176  (conf.dec_delimiter != ',') &&
177  (conf.in_dec_delimiter != ',') &&
178  (sanitized[i] == ','))) {
179  // throw an error
180  report_error("Improperly formatted numbers! (%c,%c)\n",
182  synerrors = 1;
183  break;
184  } else if ((conf.in_thou_delimiter != 0) && (sanitized[i] == conf.in_thou_delimiter)) {
185  sanitized[i] = ',';
186  } else if ((conf.in_thou_delimiter == 0) && (sanitized[i] == conf.thou_delimiter)) {
187  sanitized[i] = ',';
188  } else if ((conf.in_dec_delimiter != 0) && (sanitized[i] == conf.in_dec_delimiter)) {
189  sanitized[i] = '.';
190  } else if ((conf.in_dec_delimiter == 0) && (sanitized[i] == conf.dec_delimiter)) {
191  sanitized[i] = '.';
192  }
193  }
194  }
195 
196  /* Now, check for recursion */
197  if (recursion(sanitized)) {
198  goto exiting;
199  }
200 
201  /* now resolve the variables */
202  sanitized = flatten(sanitized);
203  Dprintf("flattened: '%s'\n", sanitized);
204 
205  /* Sanitize the input (add a newline) */
206  {
207  char *temp;
208  unsigned int len = strlen(sanitized) + 3;
209  temp = calloc(sizeof(char), len);
210  if (!temp) {
211  perror("resizing buffer");
212  goto exiting;
213  }
214  snprintf(temp, len, "%s\n", sanitized);
215  free(sanitized);
216  sanitized = temp;
217  }
218  /* reset the position tracker */
219  {
220  extern int column;
221 
222  column = 0;
223  }
224  /* Evaluate the Expression
225  */
226  {
227  struct yy_buffer_state *yy = yy_scan_string(sanitized);
228 
229  yyparse();
230  yy_delete_buffer(yy);
231  }
232 
233  if (open_file) {
234  char *filename = open_file;
235  int retval;
236 
237  open_file = NULL;
238  Dprintf("open_file\n");
239  retval = loadState(filename, 1);
240  if (retval) {
241  report_error("Could not load file (%s).",
242  (char *)strerror(retval));
243  }
244  }
245 exiting:
246  /* exiting */
247  free(sanitized);
248 } /*}}} */
249 
250 static size_t
251 find_alpha(const char *str)
252 {
253  const size_t len = strlen(str);
254  size_t i = 0;
255 
256  while ((i < len) && str[i] && !isalpha((int)str[i])) {
257  switch (str[i]) {
258  case '\\':
259  do {
260  i++;
261  } while ((i < len) && str[i] && isalpha((int)str[i]));
262  break;
263  case '\'':
264  {
265  char *tailquote = strchr(str + i + 1, '\'');
266  if (tailquote == NULL) { return len; } else {
267  i = (tailquote) - (str);
268  }
269  break;
270  }
271  case '0':
272  switch (str[i + 1]) {
273  case 'b': case 'x': i += 2; break;
274  default: i++; break;
275  }
276  break;
277  default: i++; break;
278  }
279  }
280  return i;
281 }
282 
283 static char *
284 evaluate_var(const char *varname,
285  struct answer *aptr)
286 {
287  struct answer a;
288  char *varvalue = NULL;
289 
290  // if it's a variable, evaluate it
291  a = getvar_full(varname);
292  if (!a.err) { // it is a var
293  Number f;
294 
295  num_init(f);
296  if (a.exp) { // it is an expression
297  parseme(a.exp);
298  num_set(f, last_answer);
299  } else { // it is a value
300  num_set(f, a.val);
301  num_free(a.val);
302  }
303  // get the number
304  {
305  char junk;
306 
307  // This value must fully reproduce the contents of f (thus, the -2 in arg 4)
308  varvalue = num_to_str_complex(f, 10, 0, -2, 1, &junk);
309  }
310  num_free(f);
311  } else { // not a known var: itza literal (e.g. cos)
312  varvalue = (char *)strdup(varname);
313  }
314  *aptr = a;
315  assert(varvalue != NULL);
316  return varvalue;
317 }
318 
319 static char *
320 extract_var(char *str,
321  size_t *len)
322 {
323  const size_t max = strlen(str);
324  size_t i = 0;
325  char *var;
326 
327  while (i < max &&
328  (isalpha((int)str[i]) || str[i] == '_' ||
329  str[i] == ':' || isdigit((int)str[i]))) {
330  i++;
331  }
332 
333  if (i == 0) {
334  return NULL;
335  }
336  var = malloc((i + 1) * sizeof(char));
337  memcpy(var, str, i);
338  var[i] = 0;
339  if (len) { *len = i; }
340  return var;
341 }
342 
343 /* this function should probably stop flattening if it sees a comment, but
344  * that's so rare (and hardly processor intensive) that it's not worth digging
345  * at the moment */
346 static char *
347 flatten(char *str)
348 { /*{{{ */
349  char *curs = str, *eov, *nstr;
350  char *varname, *varvalue;
351  size_t changedlen;
352  struct answer a;
353  char standard_output_save = standard_output;
354 
355  standard_output = 0;
356 
357  if (*str == '\\') {
358  standard_output = standard_output_save;
359  return str;
360  }
361  curs = strchr(str, '=');
362  if (!curs || !*curs || (*(curs + 1) == '=')) {
363  curs = str;
364  }
365 
366  while (curs && *curs) {
367  // search for the first letter of a possible variable
368  size_t max = strlen(curs);
369  size_t alpha = find_alpha(curs);
370  if (alpha == max) {
371  break;
372  }
373  curs = curs + alpha;
374  // pull out that variable
375  {
376  size_t varlen = 0;
377 
378  varname = extract_var(curs, &varlen);
379  eov = curs + varlen;
380  }
381 
382  varvalue = evaluate_var(varname, &a);
383  assert(varvalue);
384  {
385  size_t nlen = strlen(varvalue);
386 
387  // now, put it back in the string
388  // it is a var, and needs parenthesis
389  changedlen = strlen(str) + nlen - strlen(varname) + 1;
390  free(varname);
391  }
392 
393  if (!a.err) {
394  changedlen += 2; // space for parens if it's a variable
395  }
396  nstr = malloc(changedlen);
397  if (!nstr) { // not enough memory
398  perror("flatten: ");
399  exit(EXIT_FAILURE);
400  }
401  {
402  char *fromstring = str;
403  char *tostring = nstr;
404 
405  // nstr is the new string, str is the input string
406  while (fromstring != curs) { // copy up to the curs (the beginning of the var name)
407  *tostring = *fromstring;
408  ++fromstring;
409  ++tostring;
410  }
411  if (!a.err) {
412  *tostring = '(';
413  ++tostring;
414  }
415  fromstring = varvalue;
416  while (fromstring && *fromstring) {
417  *tostring = *fromstring;
418  ++fromstring;
419  ++tostring;
420  }
421  if (!a.err) {
422  *tostring = ')';
423  ++tostring;
424  }
425  curs = tostring;
426  fromstring = eov;
427  while (fromstring && *fromstring) {
428  *tostring = *fromstring;
429  ++fromstring;
430  ++tostring;
431  }
432  *tostring = 0;
433  free(str);
434  str = nstr;
435  }
436  free(varvalue);
437  }
438  standard_output = standard_output_save;
439  return str;
440 } /*}}} */
441 
442 static int
443 recursion(char *str)
444 { /*{{{ */
445  List vlist = NULL;
446  int retval = 0;
447  char *righthand;
448 
449  // do not examine commands
450  if (*str == '\\') {
451  return 0;
452  }
453  // do not examine the left side of an assignment
454  righthand = strchr(str, '=');
455  if (!righthand || !*righthand || (*(righthand + 1) == '=')) {
456  righthand = str;
457  }
458  vlist = extract_vars(righthand);
459  while (listLen(vlist) > 0) {
460  char *varname = (char *)getHeadOfList(vlist);
461 
462  if (retval == 0) {
463  retval = find_recursion(varname);
464  }
465  free(varname);
466  }
467  return retval;
468 } /*}}} */
469 
470 static int
471 find_recursion(char *instring)
472 { /*{{{ */
473  List vl = NULL;
474  int retval;
475 
476  addToList(&vl, (char *)strdup(instring));
477  retval = find_recursion_core(vl);
478  free(getHeadOfList(vl));
479  return retval;
480 } /*}}} */
481 
482 static int
484 { /*{{{ */
485  List newvars = NULL;
486  ListIterator oldvarsIterator;
487  int retval = 0;
488  struct answer a;
489  char *newVarname = NULL;
490 
491  a = getvar_full((char *)peekAheadInList(oldvars));
492  if (a.err) {
493  return 0;
494  }
495  if (!a.exp) {
496  num_free(a.val);
497  return 0;
498  }
499 
500  newvars = extract_vars(a.exp);
501  oldvarsIterator = getListIterator(oldvars);
502  // for each variable in that expression (i.e. each entry in newvars)
503  // see if we've seen it before (i.e. it's in oldvars)
504  while (listLen(newvars) > 0) {
505  newVarname = (char *)getHeadOfList(newvars);
506  char *oldVarname;
507  while ((oldVarname =
508  (char *)nextListElement(oldvarsIterator)) != NULL) {
509  if (!strcmp(newVarname, oldVarname)) {
511  ("%s was found twice in symbol descent. Recursive variables are not allowed.",
512  newVarname);
513  // free the rest of the newvars list
514  do {
515  free(newVarname);
516  } while ((newVarname =
517  (char *)getHeadOfList(newvars)) != NULL);
518  freeListIterator(oldvarsIterator);
519  return 1;
520  }
521  }
522  // now see if it has recursion
523  addToListHead(&oldvars, newVarname);
524  retval = find_recursion_core(oldvars);
525  getHeadOfList(oldvars);
526  resetListIterator(oldvarsIterator);
527  free(newVarname);
528  if (retval != 0) {
529  break;
530  }
531  }
532  // make sure newvars is empty (so all that memory gets freed)
533  while ((newVarname = (char *)getHeadOfList(newvars)) != NULL) {
534  free(newVarname);
535  }
536  freeListIterator(oldvarsIterator);
537  return retval;
538 } /*}}} */
539 
540 void
541 report_error(const char *err_fmt,
542  ...)
543 { /*{{{ */
544  extern char *errstring;
545  extern int errloc;
546  extern int column;
547  extern int lines;
548  extern int show_line_numbers;
549  char *tempstring;
550  unsigned int len;
551  va_list ap;
552  char *this_error;
553 
554  va_start(ap, err_fmt);
555 
556  this_error = calloc(strlen(err_fmt) + 1000, sizeof(char));
557  vsnprintf(this_error, strlen(err_fmt) + 1000, err_fmt, ap);
558  len = strlen(this_error) + 100;
559 
560  va_end(ap);
561 
562  /* okay, now this_error has the current error text in it */
563 
564  if (errstring) {
565  len += strlen(errstring);
566  }
567  tempstring = calloc(len, sizeof(char));
568  if (errstring) {
569  if (show_line_numbers) {
570  snprintf(tempstring, len, "%s\nError on line %i: %s", errstring,
571  lines, this_error);
572  } else {
573  snprintf(tempstring, len, "%s\n%s", errstring, this_error);
574  }
575  free(errstring);
576  } else {
577  if (show_line_numbers) {
578  snprintf(tempstring, len, "Error on line %i: %s", lines,
579  this_error);
580  } else {
581  snprintf(tempstring, len, "%s", this_error);
582  }
583  }
584  errstring = tempstring;
585  free(this_error);
586  if (errloc == -1) {
587  errloc = column;
588  }
589 } /*}}} */
590 
591 void
593 { /*{{{ */
594  char *temp;
595 
596  Dprintf("set_prettyanswer\n");
597  if (pretty_answer) {
599  }
600  Dprintf("set_prettyanswer - call print_this_result\n");
601  temp = print_this_result(num, standard_output, NULL, NULL);
602  Dprintf("set_prettyanswer: %s\n", temp);
603  if (temp) {
604  pretty_answer = (char *)strdup(temp);
605  } else {
606  pretty_answer = NULL;
607  }
608  Dprintf("set_prettyanswer - done\n");
609 } /*}}} */
610 
611 static char *
612 print_this_result_dbl(const double result,
613  int output,
614  char *nad,
615  char **es)
616 { /*{{{ */
617  char format[10];
618  static char *tmp;
619  static char pa_dyn = 1;
620  extern char *errstring;
621  unsigned int decimal_places = 0;
622 
623  Dprintf("print_this_result_dbl(%f)\n", result);
624  /* Build the "format" string, that will be used in an snprintf later */
625  switch (conf.output_format) { /*{{{ */
626  case DECIMAL_FORMAT:
627  if (pa_dyn) {
628  tmp = realloc(pa, sizeof(char) * 310);
629  } else {
630  tmp = pa = malloc(sizeof(char) * 310);
631  pa_dyn = 1;
632  }
633  if (!tmp) {
634  free(pa);
635  pa = "Not Enough Memory";
636  pa_dyn = 0;
637  return pa;
638  } else {
639  pa = tmp;
640  }
641  if (conf.precision > -1) {
642  decimal_places = conf.precision;
643  switch (conf.engineering) {
644  case never:
645  snprintf(format, 10, "%%1.%if", conf.precision);
646  break;
647  case always:
648  snprintf(format, 10, "%%1.%ie", conf.precision);
649  break;
650  case automatic:
651  snprintf(format, 10, "%%1.%ig", conf.precision);
652  break;
653  }
654  Dprintf("precision was specified as %i, format string is \"%s\"\n", conf.precision, format);
655  } else {
656  switch (conf.engineering) {
657  case never:
658  strncpy(format, "%f", 10);
659  break;
660  case always:
661  strncpy(format, "%e", 10);
662  break;
663  case automatic:
664  strncpy(format, "%g", 10);
665  break;
666  }
667  Dprintf("precision is automatic, format string is \"%s\"\n", format);
668  if (fabs(result) < 10.0) {
669  decimal_places = 6;
670  } else if (fabs(result) < 100.0) {
671  decimal_places = 4;
672  } else if (fabs(result) < 1000.0) {
673  decimal_places = 3;
674  } else if (fabs(result) < 10000.0) {
675  decimal_places = 2;
676  } else if (fabs(result) < 100000.0) {
677  decimal_places = 1;
678  } else {
679  decimal_places = 0;
680  }
681  }
682  break;
683  case OCTAL_FORMAT:
684  if (pa_dyn) {
685  tmp = realloc(pa, sizeof(char) * 14);
686  } else {
687  tmp = pa = malloc(sizeof(char) * 14);
688  pa_dyn = 1;
689  }
690  if (!tmp) {
691  free(pa);
692  pa = "Not Enough Memory";
693  pa_dyn = 0;
694  return pa;
695  } else {
696  pa = tmp;
697  }
698  snprintf(format, 10, conf.print_prefixes ? "%%#o" : "%%o");
699  break;
700  case HEXADECIMAL_FORMAT:
701  if (pa_dyn) {
702  tmp = realloc(pa, sizeof(char) * 11);
703  } else {
704  tmp = pa = malloc(sizeof(char) * 11);
705  pa_dyn = 1;
706  }
707  if (!tmp) {
708  free(pa);
709  pa = "Not Enough Memory";
710  pa_dyn = 0;
711  return pa;
712  } else {
713  pa = tmp;
714  }
715  snprintf(format, 10, conf.print_prefixes ? "%%#x" : "%%x");
716  break;
717  case BINARY_FORMAT:
718  // Binary Format can't just use a format string, so
719  // we have to handle it later
720  if (pa_dyn) {
721  free(pa);
722  }
723  pa = NULL;
724  pa_dyn = 1;
725  break;
726  } /*}}} */
727 
728  if (isinf(result)) {
729  // if it is infinity, print "Infinity", regardless of format
730  if (pa_dyn) {
731  tmp = realloc(pa, sizeof(char) * 11);
732  } else {
733  tmp = pa = malloc(sizeof(char) * 11);
734  pa_dyn = 1;
735  }
736  if (!tmp) {
737  free(pa);
738  pa = "Not Enough Memory";
739  pa_dyn = 0;
740  return pa;
741  } else {
742  pa = tmp;
743  }
744  snprintf(pa, 11, "Infinity");
745  not_all_displayed = 0;
746  } else if (isnan(result)) {
747  // if it is not a number, print "Not a Number", regardless of format
748  if (pa_dyn) {
749  tmp = realloc(pa, sizeof(char) * 13);
750  } else {
751  tmp = pa = malloc(sizeof(char) * 13);
752  pa_dyn = 1;
753  }
754  if (!tmp) {
755  free(pa);
756  pa = "Not Enough Memory";
757  pa_dyn = 0;
758  return pa;
759  } else {
760  pa = tmp;
761  }
762  snprintf(pa, 13, "Not a Number");
763  not_all_displayed = 0;
764  } else {
765  char *curs;
766 
767  Dprintf("normal numbers (format: %s)\n", format);
768  switch (conf.output_format) { /*{{{ */
769  case DECIMAL_FORMAT:
770  {
771  double junk;
772 
773  Dprintf("fabs = %f, conf.engineering = %i, conf.print_ints = %i\n", fabs(modf(result, &junk)), conf.engineering, conf.print_ints);
774  /* This is the big call */
775  /* translation: if we don't have to handle the print_ints special case,
776  * then we can just use the existing format. */
777  if ((fabs(modf(result, &junk)) != 0.0) ||
778  !conf.print_ints) {
779  snprintf(pa, 310, format, result);
780  } else {
781  /* this is the print_ints special case
782  * (note that we strip trailing zeros) */
783  snprintf(pa, 310, "%1.0f", result);
784  }
785  Dprintf("pa (unlocalized): %s\n", pa);
786  /* was it as good for you as it was for me?
787  * now, you must localize it */
788  strswap('.', conf.dec_delimiter, pa);
789 
790  Dprintf("pa: %s\n", pa);
791  switch (conf.rounding_indication) {
793  Dprintf("simple\n");
795  (modf(result * pow(10, decimal_places), &junk)) ?
796  1 : 0;
797  break;
799  Dprintf("sigfig\n");
800  if (sig_figs < UINT32_MAX) {
801  unsigned int t = count_digits(pa);
802 
803  Dprintf("digits in pa: %u (%u)\n", t, sig_figs);
804  if ((pa[0] == '0') && (pa[1] != '\0')) {
805  --t;
806  } else if ((pa[0] == '-') && (pa[1] == '0')) {
807  --t;
808  }
809  not_all_displayed = (t < sig_figs);
810  } else {
811  not_all_displayed = 1;
812  }
813  break;
814  default:
816  Dprintf("none\n");
817  not_all_displayed = 0;
818  break;
819  }
820  break;
821  }
822  case HEXADECIMAL_FORMAT:
823  curs = pa + (conf.print_prefixes ? 2 : 0);
824  strswap('.', conf.dec_delimiter, pa);
825  goto hexoct_body;
826  case OCTAL_FORMAT:
827  curs = pa + (conf.print_prefixes ? 1 : 0);
828 hexoct_body:
829  {
830  long int temp = result;
831 
832  snprintf(pa, 310, format, temp);
835  if (sig_figs < UINT32_MAX) {
836  unsigned int t = 0;
837  while (curs && *curs) {
838  ++t;
839  ++curs;
840  }
841  not_all_displayed = (t < sig_figs);
842  } else {
843  not_all_displayed = 0;
844  }
845  } else {
846  not_all_displayed = 0;
847  }
848  }
849  strswap('.', conf.dec_delimiter, pa);
850  break;
851  case BINARY_FORMAT:
852  {
853  int i, place = -1;
854 
855  // if it is binary, format it, and print it
856  // first, find the upper limit
857  for (i = 1; place == -1; ++i) {
858  if (result < pow(2.0, i)) {
859  place = i - 1;
860  }
861  }
862  pa = calloc(sizeof(char),
863  (place + (conf.print_prefixes * 2) + 1));
864  if (!pa) {
865  pa = "Not Enough Memory";
866  pa_dyn = 0;
867  return pa;
868  }
869  if (conf.print_prefixes) {
870  pa[0] = '0';
871  pa[1] = 'b';
872  }
873  // print it
874  {
875  double temp = result;
876  for (i = conf.print_prefixes * 2; place >= 0; ++i) {
877  double t = pow(2.0, place);
878 
879  if (temp >= t) {
880  pa[i] = '1';
881  temp -= t;
882  } else {
883  pa[i] = '0';
884  }
885  --place;
886  }
887  }
888  pa[i + 1] = 0;
889 
890  if (sig_figs < UINT32_MAX) {
894  count_digits(pa + (conf.print_prefixes ? 2 : 0)) <
895  sig_figs;
896  } else {
897  not_all_displayed = 0;
898  }
899  } else {
900  not_all_displayed = 0;
901  }
902  strswap('.', conf.dec_delimiter, pa);
903  } // binary format
904  } /*}}} */
905  } // if
906 
907  if (conf.print_commas) {
908  char *str = add_commas(pa, conf.output_format);
909 
910  if (str) {
911  free(pa);
912  pa = str;
913  }
914  }
915 
916  if (output) {
918  }
919  if (nad) { *nad = not_all_displayed; }
920  if (es) { *es = errstring; }
921 
922  return pa;
923 } /*}}} */
924 
925 char *
927  int output,
928  char *nad,
929  char **es)
930 { /*{{{ */
931  extern char *errstring;
932  unsigned int base = 0;
933 
934  Dprintf("print_this_result (%f) in format %i\n",
935  num_get_d(result), conf.output_format);
936  // output in the proper base and format
937  switch (conf.output_format) {
938  case HEXADECIMAL_FORMAT:
939  base = 16;
940  break;
941  default:
942  case DECIMAL_FORMAT:
943  // if you want precision_guard and automatic precision,
944  // then we have to go with the tried and true "double" method
945  // ... unless it's an int and you want ints printed whole
946 
947  // I know that DBL_EPSILON can be calculated like so:
948  // 2^(mpfr_get_prec(result)-1) HOWEVER, printf magically handles
949  // numbers like 5.1 that I don't even wanna begin to think about
950  if (conf.precision_guard && (conf.precision < 0)) {
951  Dprintf("precision guard and automatic precision\n");
952  if (!conf.print_ints || !is_int(result)) {
953  // XXX: this doesn't work for *huge* numbers, like 100!+0.1
954  Dprintf("no print_ints (%i) or it isn't an int (%i)\n", (int)conf.print_ints, (int)is_int(result));
955  // XXX: what is the following if() for?
956  // if (mpfr_get_d(result, GMP_RNDN) !=
957  // mpfr_get_si(result, GMP_RNDN)) {
958  double res = num_get_d(result);
959 
960  if (fabs(res) < DBL_EPSILON) {
961  res = 0.0;
962  }
963  return print_this_result_dbl(res, output, nad, es);
964  // }
965  }
966  }
967  base = 10;
968  break;
969  case OCTAL_FORMAT:
970  base = 8;
971  break;
972  case BINARY_FORMAT:
973  base = 2;
974  break;
975  }
976  if (pa != NULL) {
977  free(pa);
978  }
979  not_all_displayed = 0;
982  Dprintf("not_all_displayed = %i\n", not_all_displayed);
983 
984  /* now, decide whether it's been rounded or not */
985  if (num_is_inf(result) || num_is_nan(result)) {
986  // if it is infinity, it's all there ;)
987  not_all_displayed = 0;
988  } else if (not_all_displayed == 0) {
989  /* rounding guess */
990  switch (conf.rounding_indication) {
992  {
993  char *pa2, junk;
994 
995  Dprintf("simple full\n");
996 
997  pa2 =
998  num_to_str_complex(result, base, conf.engineering, -2,
999  conf.print_prefixes, &junk);
1000  not_all_displayed = (strlen(pa) < strlen(pa2));
1001  free(pa2);
1002  break;
1003  }
1005  /* sig_figs is how many we need to display */
1006  Dprintf("sigfig full\n");
1007  if (sig_figs < UINT32_MAX) {
1008  unsigned int t = count_digits(pa);
1009 
1010  Dprintf("digits in pa: %u (%u)\n", t, sig_figs);
1011  not_all_displayed = (t < sig_figs);
1012  } else {
1013  not_all_displayed = 0;
1014  }
1015  break;
1016  default:
1018  Dprintf("none full\n");
1019  not_all_displayed = 0;
1020  break;
1021  }
1022  }
1024  Dprintf("clearing rounding indication\n");
1025  not_all_displayed = 0;
1026  }
1027  strswap('.', conf.dec_delimiter, pa);
1028  // add commas
1029  if (conf.print_commas) {
1030  char *str = add_commas(pa, conf.output_format);
1031 
1032  if (str) {
1033  free(pa);
1034  pa = str;
1035  }
1036  }
1037 
1038  if (output) {
1040  }
1041  if (nad) { *nad = not_all_displayed; }
1042  if (es) { *es = errstring; }
1043 
1044  return pa;
1045 } /*}}} */
1046 
1047 void
1049  const Number first,
1050  const enum operations op,
1051  const Number second)
1052 { /*{{{ */
1053  if (compute) {
1054  Number temp;
1055 
1056  num_init(temp);
1057  Dprintf("simple_exp: %f %i %f\n", num_get_d(first), op,
1058  num_get_d(second));
1059 
1060  switch (op) {
1061  default:
1062  num_set_d(output, 0.0);
1063  break;
1064  case wequal:
1065  num_set_ui(output, num_is_equal(first, second));
1066  break;
1067  case wnequal:
1068  num_set_ui(output, !num_is_equal(first, second));
1069  break;
1070  case wgt:
1071  num_set_ui(output, num_is_greater(first, second));
1072  break;
1073  case wlt:
1074  num_set_ui(output, num_is_less(first, second));
1075  break;
1076  case wgeq:
1077  num_set_ui(output, num_is_greaterequal(first, second));
1078  break;
1079  case wleq:
1080  num_set_ui(output, num_is_lessequal(first, second));
1081  break;
1082  case wplus:
1083  num_add(output, first, second);
1084  break;
1085  case wminus:
1086  num_sub(output, first, second);
1087  break;
1088  case wmult:
1089  num_mul(output, first, second);
1090  break;
1091  case wdiv:
1092  num_div(output, first, second);
1093  break;
1094  case wpow:
1095  num_pow(output, first, second);
1096  break;
1097  case wor:
1098  num_set_ui(output, (!num_is_zero(first)) ||
1099  (!num_is_zero(second)));
1100  break;
1101  case wand:
1102  num_set_ui(output, (!num_is_zero(first)) &&
1103  (!num_is_zero(second)));
1104  break;
1105  case wbor:
1106  num_bor(output, first, second);
1107  break;
1108  case wband:
1109  num_band(output, first, second);
1110  break;
1111  case wbxor:
1112  num_bxor(output, first, second);
1113  break;
1114  case wlshft:
1115  num_set_ui(temp, 2);
1116  num_pow(temp, temp, second);
1117  num_mul(output, first, temp);
1118  break;
1119  case wrshft:
1120  num_set_ui(temp, 2);
1121  num_pow(temp, temp, second);
1122  num_div(output, first, temp);
1123  if (is_int(first)) {
1124  num_trunc(output, output);
1125  }
1126  break;
1127  case wmod:
1128  if (num_is_zero(second)) {
1129  num_set_nan(output);
1130  } else {
1131  /* divide, round to zero, multiply, subtract
1132  *
1133  * in essence, find the value x in the equation:
1134  * first = second * temp + x */
1135  num_div(output, first, second);
1136  if (conf.c_style_mod) {
1137  num_rintz(output, output); // makes zeros work
1138  } else {
1139  if (num_sign(first) >= 0) {
1140  num_floor(output, output);
1141  } else {
1142  num_ceil(output, output);
1143  }
1144  }
1145  num_mul(output, output, second);
1146  num_sub(output, first, output);
1147  }
1148  break;
1149  }
1150  Dprintf("returns: %f\n", num_get_d(output));
1151  num_free(temp);
1152  return;
1153  } else {
1154  num_set_ui(output, 0);
1155  return;
1156  }
1157 } /*}}} */
1158 
1159 void
1161  const enum functions func,
1162  Number input)
1163 { /*{{{ */
1164  if (compute) {
1165  Number temp;
1166 
1167  num_init(temp);
1168  if (!conf.use_radians) {
1169  switch (func) {
1170  case wsin:
1171  case wcos:
1172  case wtan:
1173  case wcot:
1174  case wsec:
1175  case wcsc:
1176  num_const_pi(temp);
1177  num_mul(input, input, temp);
1178  num_div_ui(input, input, 180);
1179  break;
1180  case wasin:
1181  case wacos:
1182  case watan:
1183  case wacot:
1184  case wasec:
1185  case wacsc:
1186  num_const_pi(temp);
1187  num_pow_si(temp, temp, -1);
1188  num_mul_ui(temp, temp, 180);
1189  break;
1190  default:
1191  break;
1192  }
1193  }
1194  switch (func) {
1195  case wsin:
1196  num_sin(output, input);
1197  break;
1198  case wcos:
1199  num_cos(output, input);
1200  break;
1201  case wtan:
1202  num_tan(output, input);
1203  break;
1204  case wcot:
1205  num_cot(output, input);
1206  break;
1207  case wsec:
1208  num_sec(output, input);
1209  break;
1210  case wcsc:
1211  num_csc(output, input);
1212  break;
1213  case wasin:
1214  num_asin(output, input);
1215  if (!conf.use_radians) {
1216  num_mul(output, output, temp);
1217  }
1218  break;
1219  case wacos:
1220  num_acos(output, input);
1221  if (!conf.use_radians) {
1222  num_mul(output, output, temp);
1223  }
1224  break;
1225  case watan:
1226  num_atan(output, input);
1227  if (!conf.use_radians) {
1228  num_mul(output, output, temp);
1229  }
1230  break;
1231  case wacot:
1232  num_pow_si(output, input, -1);
1233  num_atan(output, output);
1234  if (!conf.use_radians) {
1235  num_mul(output, output, temp);
1236  }
1237  break;
1238  case wasec:
1239  num_pow_si(output, input, -1);
1240  num_acos(output, output);
1241  if (!conf.use_radians) {
1242  num_mul(output, output, temp);
1243  }
1244  break;
1245  case wacsc:
1246  num_pow_si(output, input, -1);
1247  num_asin(output, output);
1248  if (!conf.use_radians) {
1249  num_mul(output, output, temp);
1250  }
1251  break;
1252  case wsinh:
1253  num_sinh(output, input);
1254  break;
1255  case wcosh:
1256  num_cosh(output, input);
1257  break;
1258  case wtanh:
1259  num_tanh(output, input);
1260  break;
1261  case wcoth:
1262  num_coth(output, input);
1263  break;
1264  case wsech:
1265  num_sech(output, input);
1266  break;
1267  case wcsch:
1268  num_csch(output, input);
1269  break;
1270  case wasinh:
1271  num_asinh(output, input);
1272  break;
1273  case wacosh:
1274  num_acosh(output, input);
1275  break;
1276  case watanh:
1277  num_atanh(output, input);
1278  break;
1279  case wacoth:
1280  num_acoth(output, input);
1281  break;
1282  case wasech:
1283  num_asech(output, input);
1284  break;
1285  case wacsch:
1286  num_acsch(output, input);
1287  break;
1288  case wlog:
1289  num_log10(output, input);
1290  break;
1291  case wlogtwo:
1292  num_log2(output, input);
1293  break;
1294  case wln:
1295  num_log(output, input);
1296  break;
1297  case wround:
1298  num_rint(output, input);
1299  break;
1300  case wneg:
1301  num_neg(output, input);
1302  break;
1303  case wnot:
1304  num_set_ui(output, num_is_zero(input));
1305  break;
1306  case wabs:
1307  num_abs(output, input);
1308  break;
1309  case wsqrt:
1310  num_sqrt(output, input);
1311  break;
1312  case wfloor:
1313  num_floor(output, input);
1314  break;
1315  case wceil:
1316  num_ceil(output, input);
1317  break;
1318  case wrand:
1319  while (num_random(output) != 0) ;
1320  num_mul(output, output, input);
1321  if (num_cmp_si(input, 0) < 0) {
1322  num_mul_si(output, output, -1);
1323  }
1324  break;
1325  case wirand:
1326  while (num_random(output) != 0) ;
1327  num_mul(output, output, input);
1328  if (num_cmp_si(input, 0) < 0) {
1329  num_mul_si(output, output, -1);
1330  }
1331  num_rint(output, output);
1332  break;
1333  case wcbrt:
1334  num_cbrt(output, input);
1335  break;
1336  case wexp:
1337  num_exp(output, input);
1338  break;
1339  case wfact:
1340  num_factorial(output, num_get_ui(input));
1341  break;
1342  case wcomp:
1343  num_comp(output, input);
1344  break;
1345 #ifdef HAVE_MPFR_22
1346  case weint:
1347  num_eint(output, input);
1348  break;
1349 #endif
1350  case wgamma:
1351  num_gamma(output, input);
1352  break;
1353 #ifdef HAVE_MPFR_22
1354  case wlngamma:
1355  num_lngamma(output, input);
1356  break;
1357 #endif
1358  case wzeta:
1359  num_zeta(output, input);
1360  break;
1361  case wsinc:
1362  num_sinc(output, input);
1363  break;
1364  case wbnot:
1365  num_bnot(output, input);
1366  break;
1367  default:
1368  num_set(output, input);
1369  break;
1370  }
1371  num_free(temp);
1372  return;
1373  } else {
1374  num_set_ui(output, 0);
1375  return;
1376  }
1377 } /*}}} */
1378 
1379 char *
1380 output_string(const unsigned int o)
1381 { /*{{{ */
1382  switch (o) {
1383  case HEXADECIMAL_FORMAT:
1384  return "hexadecimal format (0xf)";
1385 
1386  case OCTAL_FORMAT:
1387  return "octal format (08) ";
1388 
1389  case BINARY_FORMAT:
1390  return "binary format (0b1) ";
1391 
1392  case DECIMAL_FORMAT:
1393  return "decimal format (9) ";
1394 
1395  default:
1396  return "error, unknown format ";
1397  }
1398 } /*}}} */
1399 
1400 /* vim:set expandtab: */
wacsc
Definition: calculator.h:43
isnan_ld
static int isnan_ld(long double x)
Definition: calculator.c:34
add_commas.h
num_cosh
void num_cosh(Number ret, const Number n)
Definition: number.c:366
wrand
Definition: calculator.h:65
wacosh
Definition: calculator.h:51
wmult
Definition: calculator.h:80
_conf::precision_guard
unsigned int precision_guard
Definition: calculator.h:136
_conf::engineering
enum engineering_modes engineering
Definition: calculator.h:129
simple_exp
void simple_exp(Number output, const Number first, const enum operations op, const Number second)
Definition: calculator.c:1048
_conf::c_style_mod
unsigned int c_style_mod
Definition: calculator.h:144
num_zeta
#define num_zeta(ret, n)
Definition: number.h:103
show_answer
void show_answer(char *err, int uncertain, char *answer)
Definition: main.c:470
peekAheadInList
void * peekAheadInList(List)
Definition: list.c:343
wnot
Definition: calculator.h:30
yy_delete_buffer
void yy_delete_buffer(struct yy_buffer_state *)
strswap
void strswap(const char sw, const char ap, char *str)
Definition: string_manip.c:44
OCTAL_FORMAT
#define OCTAL_FORMAT
Definition: calculator.h:164
wlt
Definition: calculator.h:92
wsin
Definition: calculator.h:32
wirand
Definition: calculator.h:66
_list_iterator
Definition: list.c:27
wcbrt
Definition: calculator.h:75
num_cmp_si
int num_cmp_si(const Number n, const int si)
Definition: number.c:726
uint32_max.h
num_asech
void num_asech(Number ret, const Number n)
Definition: number.c:426
not_all_displayed
char not_all_displayed
Definition: calculator.c:107
strchr
#define strchr
Definition: variables.h:11
print_this_result_dbl
static char * print_this_result_dbl(const double result, int output, char *nad, char **es)
Definition: calculator.c:612
wfloor
Definition: calculator.h:63
conf
struct _conf conf
Definition: calculator.c:111
wbnot
Definition: calculator.h:31
num_log10
void num_log10(Number ret, const Number n)
Definition: number.c:266
BINARY_FORMAT
#define BINARY_FORMAT
Definition: calculator.h:166
num_factorial
void num_factorial(Number ret, unsigned int n)
Definition: number.c:250
string_manip.h
wsec
Definition: calculator.h:36
wlshft
Definition: calculator.h:94
wneg
Definition: calculator.h:60
yy_buffer_state
Definition: scanner.c:197
calculator.h
wzeta
Definition: calculator.h:73
flatten
static char * flatten(char *str)
Definition: calculator.c:347
num_sqrt
void num_sqrt(Number ret, const Number n)
Definition: number.c:190
count_digits
unsigned int count_digits(const char *)
Definition: string_manip.c:76
_conf::use_radians
unsigned int use_radians
Definition: calculator.h:131
pa
char * pa
Definition: calculator.c:108
output_string
char * output_string(const unsigned int o)
Definition: calculator.c:1380
num_sec
void num_sec(Number ret, const Number n)
Definition: number.c:750
num_cbrt
void num_cbrt(Number ret, const Number n)
Definition: number.c:200
num_is_inf
int num_is_inf(const Number n)
Definition: number.c:655
wtan
Definition: calculator.h:34
_conf::print_prefixes
unsigned int print_prefixes
Definition: calculator.h:133
_conf::print_ints
unsigned int print_ints
Definition: calculator.h:139
free
void free(void *)
num_random
int num_random(Number n)
Definition: number.c:594
yyparse
int yyparse(void)
Definition: parser.c:1563
wpow
Definition: calculator.h:83
num_pow
void num_pow(Number ret, const Number n, const Number exp)
Definition: number.c:210
wmod
Definition: calculator.h:82
num_asinh
void num_asinh(Number ret, const Number n)
Definition: number.c:386
wcomp
Definition: calculator.h:69
isnan_d
static int isnan_d(double x)
Definition: calculator.c:28
extract_vars
List extract_vars(char *str)
Definition: extract_vars.c:16
parseme
void parseme(const char *pthis)
Definition: calculator.c:130
functions
functions
Definition: calculator.h:29
num_get_ui
unsigned int num_get_ui(const Number n)
Definition: number.c:451
num_acos
void num_acos(Number ret, const Number n)
Definition: number.c:336
wtanh
Definition: calculator.h:46
variables.h
num_add
void num_add(Number ret, const Number n1, const Number n2)
Definition: number.c:484
num_set_d
void num_set_d(Number n, const double d)
Definition: number.c:111
standard_output
char standard_output
Definition: calculator.c:106
find_alpha
static size_t find_alpha(const char *str)
Definition: calculator.c:251
wplus
Definition: calculator.h:78
getHeadOfList
void * getHeadOfList(List)
Definition: list.c:264
find_recursion
static int find_recursion(char *)
Definition: calculator.c:471
wminus
Definition: calculator.h:79
listLen
size_t listLen(List)
Definition: list.c:352
wbxor
Definition: calculator.h:86
weint
Definition: calculator.h:70
wbor
Definition: calculator.h:85
num_mul_si
void num_mul_si(Number ret, const Number n, const int si)
Definition: number.c:162
num_div
void num_div(Number ret, const Number n1, const Number n2)
Definition: number.c:528
num_is_greater
int num_is_greater(const Number n1, const Number n2)
Definition: number.c:671
num_asin
void num_asin(Number ret, const Number n)
Definition: number.c:326
num_csch
void num_csch(Number ret, const Number n)
Definition: number.c:786
num_const_pi
void num_const_pi(Number n)
Definition: number.c:615
num_pow_si
void num_pow_si(Number ret, const Number n, const int exp)
Definition: number.c:225
wasec
Definition: calculator.h:42
wcsc
Definition: calculator.h:37
wgeq
Definition: calculator.h:95
wasech
Definition: calculator.h:54
errstring
char * errstring
Definition: parser.c:111
wnequal
Definition: calculator.h:90
number_formatting.h
num_trunc
void num_trunc(Number ret, const Number n)
Definition: number.c:848
_conf::in_dec_delimiter
char in_dec_delimiter
Definition: calculator.h:128
num_is_lessequal
int num_is_lessequal(const Number n1, const Number n2)
Definition: number.c:689
wexp
Definition: calculator.h:67
_list
Definition: list.c:19
num_floor
void num_floor(Number ret, const Number n)
Definition: number.c:574
find_recursion_core
static int find_recursion_core(List)
Definition: calculator.c:483
isinf_d
static int isinf_d(double x)
Definition: calculator.c:52
wleq
Definition: calculator.h:96
yy_scan_string
void * yy_scan_string(const char *)
addToList
void addToList(List *, void *)
Definition: list.c:204
num_sub
void num_sub(Number ret, const Number n1, const Number n2)
Definition: number.c:495
evaluate_var
static char * evaluate_var(const char *varname, struct answer *aptr)
Definition: calculator.c:284
num_sech
void num_sech(Number ret, const Number n)
Definition: number.c:777
answer
Definition: variables.h:29
set_prettyanswer
void set_prettyanswer(const Number num)
Definition: calculator.c:592
_conf::print_commas
unsigned int print_commas
Definition: calculator.h:142
num_acoth
void num_acoth(Number ret, const Number n)
Definition: number.c:416
num_bxor
void num_bxor(Number ret, const Number n1, const Number n2)
Definition: number.c:826
num_band
void num_band(Number ret, const Number n1, const Number n2)
Definition: number.c:815
wgt
Definition: calculator.h:91
num_mul
void num_mul(Number ret, const Number n1, const Number n2)
Definition: number.c:151
num_exp
void num_exp(Number ret, const Number n)
Definition: number.c:240
_conf::rounding_indication
unsigned int rounding_indication
Definition: calculator.h:134
wcoth
Definition: calculator.h:47
_conf
Definition: calculator.h:122
last_input
char * last_input
Definition: calculator.c:109
wgamma
Definition: calculator.h:71
synerrors
int synerrors
Definition: parser.c:109
Dprintf
#define Dprintf(...)
Definition: calculator.h:23
loadState
int loadState(const char *filename, const int into_history)
Definition: files.c:261
wlngamma
Definition: calculator.h:72
num_init
void num_init(Number n)
Definition: number.c:69
operations
operations
Definition: calculator.h:77
wor
Definition: calculator.h:84
num_is_zero
int num_is_zero(const Number n)
Definition: number.c:660
Number
#define Number
Definition: number.h:23
wrshft
Definition: calculator.h:93
_conf::dec_delimiter
char dec_delimiter
Definition: calculator.h:126
_conf::in_thou_delimiter
char in_thou_delimiter
Definition: calculator.h:127
num_set
void num_set(Number n1, const Number n2)
Definition: number.c:105
num_bor
void num_bor(Number ret, const Number n1, const Number n2)
Definition: number.c:837
getvar_full
struct answer getvar_full(const char *key)
Definition: variables.c:160
wcosh
Definition: calculator.h:45
isinf
#define isinf(x)
Definition: calculator.c:41
wsinh
Definition: calculator.h:44
answer::err
unsigned int err
Definition: variables.h:33
malloc
void * malloc(size_t)
answer::exp
char * exp
Definition: variables.h:31
recursion
static int recursion(char *str)
Definition: calculator.c:443
wacot
Definition: calculator.h:41
num_div_ui
void num_div_ui(Number ret, const Number n, const unsigned int ui)
Definition: number.c:539
isinf_ld
static int isinf_ld(long double x)
Definition: calculator.c:58
wlogtwo
Definition: calculator.h:57
num_neg
void num_neg(Number ret, const Number n)
Definition: number.c:706
last_answer
Number last_answer
Definition: calculator.c:98
num_free
void num_free(Number n)
Definition: number.c:738
num_bnot
void num_bnot(Number ret, const Number n)
Definition: number.c:805
wcot
Definition: calculator.h:35
num_tan
void num_tan(Number ret, const Number n)
Definition: number.c:316
wcsch
Definition: calculator.h:49
resetListIterator
void resetListIterator(ListIterator)
Definition: list.c:398
num_coth
void num_coth(Number ret, const Number n)
Definition: number.c:768
UINT32_MAX
#define UINT32_MAX
Definition: uint32_max.h:11
num_set_ui
void num_set_ui(Number n, const unsigned int ui)
Definition: number.c:118
wround
Definition: calculator.h:59
lines
int lines
Definition: parser.c:108
getListIterator
ListIterator getListIterator(List)
Definition: list.c:362
wln
Definition: calculator.h:58
num_acosh
void num_acosh(Number ret, const Number n)
Definition: number.c:396
num_is_greaterequal
int num_is_greaterequal(const Number n1, const Number n2)
Definition: number.c:677
num_log2
void num_log2(Number ret, const Number n)
Definition: number.c:276
wfact
Definition: calculator.h:68
DECIMAL_FORMAT
#define DECIMAL_FORMAT
Definition: calculator.h:163
wacsch
Definition: calculator.h:55
wequal
Definition: calculator.h:89
never
Definition: calculator.h:102
isnan_f
static int isnan_f(float x)
Definition: calculator.c:22
isinf_f
static int isinf_f(float x)
Definition: calculator.c:46
nextListElement
void * nextListElement(ListIterator)
Definition: list.c:385
num_set_nan
void num_set_nan(Number n)
Definition: number.c:145
num_cot
void num_cot(Number ret, const Number n)
Definition: number.c:741
pretty_answer
char * pretty_answer
Definition: calculator.c:99
sig_figs
unsigned int sig_figs
Definition: calculator.c:103
HEXADECIMAL_FORMAT
#define HEXADECIMAL_FORMAT
Definition: calculator.h:165
print_this_result
char * print_this_result(const Number result, int output, char *nad, char **es)
Definition: calculator.c:926
num_sin
void num_sin(Number ret, const Number n)
Definition: number.c:296
num_sinh
void num_sinh(Number ret, const Number n)
Definition: number.c:356
wsqrt
Definition: calculator.h:62
num_atanh
void num_atanh(Number ret, const Number n)
Definition: number.c:406
add_commas
char * add_commas(const char *input, const int base)
Definition: add_commas.c:19
extract_vars.h
report_error
void report_error(const char *err_fmt,...)
Definition: calculator.c:541
num_to_str_complex
char * num_to_str_complex(const mpfr_t num, const int base, const enum engineering_modes engr, const int prec, const int prefix, char *truncated_flag)
show_line_numbers
int show_line_numbers
Definition: parser.c:113
wceil
Definition: calculator.h:64
watanh
Definition: calculator.h:52
automatic
Definition: calculator.h:102
num_sign
int num_sign(const Number n)
Definition: number.c:695
isnan
#define isnan(x)
Definition: calculator.c:17
num_comp
void num_comp(Number ret, const Number n)
Definition: number.c:795
addToListHead
void addToListHead(List *, void *)
Definition: list.c:234
num_acsch
void num_acsch(Number ret, const Number n)
Definition: number.c:436
freeListIterator
void freeListIterator(ListIterator)
Definition: list.c:406
num_cos
void num_cos(Number ret, const Number n)
Definition: number.c:306
_conf::precision
int precision
Definition: calculator.h:124
wacos
Definition: calculator.h:39
answer::val
mpfr_t val
Definition: variables.h:30
wabs
Definition: calculator.h:61
num_tanh
void num_tanh(Number ret, const Number n)
Definition: number.c:376
num_csc
void num_csc(Number ret, const Number n)
Definition: number.c:759
num_is_nan
int num_is_nan(const Number n)
Definition: number.c:650
uber_function
void uber_function(Number output, const enum functions func, Number input)
Definition: calculator.c:1160
SIG_FIG_ROUNDING_INDICATION
#define SIG_FIG_ROUNDING_INDICATION
Definition: calculator.h:170
num_abs
void num_abs(Number ret, const Number n)
Definition: number.c:716
num_rintz
void num_rintz(Number ret, const Number n)
Definition: number.c:560
_conf::thou_delimiter
char thou_delimiter
Definition: calculator.h:125
files.h
is_int
int is_int(const mpfr_t)
_conf::output_format
unsigned int output_format
Definition: calculator.h:132
extract_var
static char * extract_var(char *str, size_t *len)
Definition: calculator.c:320
SIMPLE_ROUNDING_INDICATION
#define SIMPLE_ROUNDING_INDICATION
Definition: calculator.h:169
num_sinc
void num_sinc(Number ret, const Number n)
Definition: number.c:600
watan
Definition: calculator.h:40
wsech
Definition: calculator.h:48
list.h
wasinh
Definition: calculator.h:50
num_ceil
void num_ceil(Number ret, const Number n)
Definition: number.c:584
strrchr
#define strrchr
Definition: variables.h:12
wdiv
Definition: calculator.h:81
wacoth
Definition: calculator.h:53
NO_ROUNDING_INDICATION
#define NO_ROUNDING_INDICATION
Definition: calculator.h:168
number.h
wlog
Definition: calculator.h:56
num_atan
void num_atan(Number ret, const Number n)
Definition: number.c:346
errloc
int errloc
Definition: parser.c:112
wband
Definition: calculator.h:88
num_log
void num_log(Number ret, const Number n)
Definition: number.c:286
num_is_less
int num_is_less(const Number n1, const Number n2)
Definition: number.c:683
column
int column
Definition: scanner.c:1741
wsinc
Definition: calculator.h:74
num_mul_ui
void num_mul_ui(Number ret, const Number n, const unsigned int ui)
Definition: number.c:173
always
Definition: calculator.h:102
num_rint
void num_rint(Number ret, const Number n)
Definition: number.c:550
wasin
Definition: calculator.h:38
output.h
wcos
Definition: calculator.h:33
wand
Definition: calculator.h:87
open_file
char * open_file
Definition: files.c:39
compute
char compute
Definition: calculator.c:102
num_get_d
double num_get_d(const Number n)
Definition: number.c:446
num_is_equal
int num_is_equal(const Number n1, const Number n2)
Definition: number.c:665