bc and dc Calculators

repository·master·Indexed 42 days ago

https://github.com/gavinhoward/bc

A high-performance, standards-compliant implementation of the POSIX bc and dc (RPN) calculators, including GNU and BSD extensions. It features a C math library (bcl) for software integration, support for scientific and engineering notation, and advanced mathematical functions including Karatsuba multiplication and transcendental functions.

Tokens
90.1K
Snippets
188
Records
459
Agent score
41%

What's inside bc

  1. Overview of `bc` and `dc` implementation

    master

    This project is a robust implementation of the POSIX bc calculator that includes GNU bc extensions and the BSD flavor's period (.) extension.

    Key features:

    • Dual Calculators: The binary includes both bc and dc (the reverse-polish notation calculator). dc implements all FreeBSD and GNU extensions. To use dc as a standalone binary, you can copy and rename the bc binary to dc.
    • Security: The ! command (often used for shell execution) is intentionally omitted from the dc implementation to prevent security concerns.
    • Math Library: Provides bcl, a C library containing the bc math implementation.
    • Compatibility: Designed as a drop-in replacement for existing bc implementations and is compatible with MinGW toolchains.
  2. Overview of bc arbitrary-precision arithmetic language

    master

    bc is an interactive processor for an arbitrary-precision decimal arithmetic language, standardized by POSIX. It provides unlimited precision decimal arithmetic and features a syntax similar to C. This implementation is a drop-in replacement for any standard bc (including GNU bc) but includes additional extensions and features.

    When running bc, it processes command-line files first, then reads from stdin.

  3. What is dc?

    master

    dc is an arbitrary-precision decimal calculator that uses reverse Polish notation (RPN). It utilizes a stack to store numbers and the results of computations. Arithmetic operations pop arguments off the stack and push the resulting value back onto the stack.

    If no files are provided via command-line arguments, dc reads from stdin. If files are provided, they are processed and dc exits after completion.

  4. Overview of the bc arbitrary-precision language

    master

    bc is an interactive processor for an arbitrary-precision decimal arithmetic language. It provides unlimited precision decimal arithmetic and features a syntax that is similar to C, though with specific differences.

    This implementation is a drop-in replacement for any standard bc implementation (including GNU bc) and includes additional extensions and features.

    Execution Order: After parsing command-line options, bc executes any files provided as arguments on the command line before reading from stdin.

  5. Overview of dc (arbitrary-precision decimal calculator)

    master

    dc

    dc is an arbitrary-precision decimal calculator that uses a stack (Reverse Polish Notation) to store numbers and computation results. Arithmetic operations pop arguments off the stack and push the results back onto it.

    Input/Output Behavior:

    • Input: If no files are provided on the command line, dc reads from stdin. If files are provided, they are processed and dc exits after completion. If no files or expressions are provided, it reads from stdin line-by-line (brackets must be balanced within a line).
    • Output: Non-error output is written to stdout. Error output is written to stderr.
    • Note on Redirection: Unlike some other implementations, this version of dc will issue a fatal error if it cannot write to stdout or stderr. If you are redirecting these to files or /dev/null, ensure the streams remain open to avoid unexpected exits.
  6. Overview of the bc arbitrary-precision calculator

    master

    bc is an interactive processor for an arbitrary-precision decimal arithmetic language. It is standardized by POSIX and provides unlimited precision decimal arithmetic. The language syntax is similar to C, though there are specific differences.

    This implementation is designed as a drop-in replacement for any bc implementation, including GNU bc, but includes additional extensions and features.

    Execution Order:

    1. Parse command-line options.
    2. Execute any files provided as arguments on the command line.
    3. Read from stdin.
  7. Use bc for arbitrary-precision decimal arithmetic

    master

    The bc command is an interactive processor for an arbitrary-precision decimal arithmetic language. It is a drop-in replacement for any bc implementation (including GNU bc) and provides unlimited precision decimal arithmetic. The language is similar to C but has specific differences noted in its documentation.

    When running scripts written for other bc implementations, if you encounter parse errors, it is likely because a word reserved as a keyword in this version is being used as a function, variable, or array name. You can resolve this using the -r option to reassign the keyword.

    bc [options] [file...]
  8. Understand argument consumption and error propagation

    master

    To allow for compact code, many bcl(3) functions consume their BclNumber arguments. This means the function automatically frees the memory associated with the argument. This allows you to nest calls without leaking memory:

    BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));

    Crucial: Because errors can occur during nested calls, you must check the final result with bcl_err(BclNumber) to ensure the entire operation succeeded:

    BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
    if (bcl_err(n) != BCL_ERROR_NONE) {
        // Handle the error.
    }
    BclNumber n = bcl_num_add(bcl_num_mul(a, b), bcl_num_div(c, d));
    if (bcl_err(n) != BCL_ERROR_NONE) {
        // Handle the error.
    }
  9. Understand how strings are stored as `BcNum`

    master

    To avoid the complexity of a full union/new type system for variable stacks, bc allows BcNum structs to store strings.

    **A BcNum representing a string is identified by:

    • num == NULL (the limb array is null).
    • cap == 0.

    String Metadata Storage:

    • The rdx field stores the function used to store the string.
    • The scale field stores the index of the string.

    Type Checking: When a temporary is created with a string, the result type should be set to BC_RESULT_STR rather than BC_RESULT_TEMP to facilitate easier type checking.

  10. Generate pseudo-random numbers with rand() and irand()

    master

    bc provides two operands for generating pseudo-random integers.

    Warning: These values are NOT cryptographically secure. They are reproducible with identical seed values and should only be used when a reproducible stream is essential.

    Operands

    • rand(): Returns a pseudo-random integer between 0 (inclusive) and BC_RAND_MAX (inclusive). Calling this changes the value of seed.
    • irand(E): Returns a pseudo-random integer in the range $[0, E)$.
      • E must be a positive integer. If E is negative or a non-integer, an error is raised and bc resets.
      • If $E > \text{BC_RAND_MAX}$, the function generates an unbounded integer by combining multiple random values.
      • Calling this changes the value of seed, unless $E$ is 0 or 1 (in which case 0 is returned and seed is unchanged).

    Both functions are guaranteed to be as unbiased as possible given the underlying generator.

  11. Understand number string parsing and scientific notation

    master

    When parsing number strings, bcl(3) follows these rules:

    • Only one radix (period .) is allowed.
    • Lowercase ASCII letters, symbols, or non-ASCII characters are invalid, with one exception: a single lowercase e.
    • A dash - is allowed as the first character to indicate a negative number.
    • Scientific Notation: If an e is present, the part before it is the number and the part after it must be an integer (the exponent). A dash can follow the e for a negative exponent.
    • Base Interaction: Both the number and the exponent are interpreted according to the current ibase. However, the number is always multiplied by 10^exponent regardless of the ibase.

    Examples (assuming ibase 16):

    • FFeA results in decimal 2550000000000.
    • 10e-4 results in decimal 0.0016.
  12. How bc handles errors and resets

    master

    When bc(1) encounters an error or a signal with a non-default handler, it performs a reset.

    Reset Behavior:

    1. All currently executing functions are stopped and popped off the stack (similar to exceptions).
    2. The execution point is set such that any code waiting to execute after the functions would have returned is skipped.
    3. In interactive mode, if the error was not fatal, bc(1) will prompt for more input. If the error was fatal, it exits with the appropriate return code.

    Note: This differs from GNU bc, which attempts to continue executing the statement immediately following the error.