Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
linguini1 committed Apr 15, 2024
0 parents commit d3318e0
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
BasedOnStyle: LLVM
IndentWidth: 4
ColumnLimit: 120
AllowShortIfStatementsOnASingleLine: true
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Developer artifacts
.cache/
compile_commands.json

# Compilation
*.o
quadratic
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Matteo Golin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
CC = gcc
OUT = quadratic

# Compilation warnings
WARNINGS += -Wall -Wextra -Wshadow -Wundef -Wformat=2 -Wtrampolines -Wfloat-equal
WARNINGS += -Wbad-function-cast -Wstrict-prototypes -Wpacked
WARNINGS += -Wno-aggressive-loop-optimizations -Wmissing-prototypes -Winit-self
WARNINGS += -Wmissing-declarations -Wmissing-format-attribute -Wunreachable-code
WARNINGS += -Wshift-overflow=2 -Wduplicated-cond -Wpointer-arith -Wwrite-strings
WARNINGS += -Wnested-externs -Wcast-align -Wredundant-decls
WARNINGS += -Werror=implicit-function-declaration -Wlogical-not-parentheses
WARNINGS += -Wlogical-op -Wold-style-definition -Wcast-qual -Wdouble-promotion
WARNINGS += -Wunsuffixed-float-constants -Wmissing-include-dirs -Wnormalized
WARNINGS += -Wdisabled-optimization -Wsuggest-attribute=const

# Compilation flags
CFLAGS = -O3 -lm

# Source files
SRCDIR = .
SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))

%.o: %.c
$(CC) $(CFLAGS) $(WARNINGS) -o $@ -c $<

all: $(OBJS)
$(CC) $(CFLAGS) $^ -o $(OUT)

clean:
@rm $(OBJS)
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# quadratic

A simple command line program for solving the quadratic equation. I built this purely to save me a little time when
doing algebra for my engineering homework. The quadratic formula shows up quite often in circuit problems for non-linear
circuits, and it becomes tedious to evaluate the quadratic formula each time.

# Usage

To see usage instructions for this program, please run `quadratic -h`.

Example output:

```console
[user]$ quadratic -- 1 -10 16
1.000000x^2 + -10.000000x + 16.000000
x = 8.000000
x = 2.000000

[user]$ quadratic -v y -- 1 -10 16
1.000000y^2 + 2.000000y + 3.000000
x = -1.000000 + 1.414214i
x = -1.000000 + -1.414214i

```

# Build/Installation

The build recipe is in the Makefile. Running `make all` will create a binary called `quadratic` which you can then run.

Although only tested on Linux, this program should build and run just fine on all other platforms.
176 changes: 176 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#include <getopt.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

/** Program version. */
#define VERSION "0.0.0"

/** Struct to represent a quadratic polynomial of format ax^2 + bx + c. */
struct quadratic_t {
double a; /**< The a coefficient. */
double b; /**< The b coefficient. */
double c; /**< The c coefficient. */
};

/** Struct to represent a complex number. */
struct complex_t {
double re; /**< The real component. */
double im; /**< The imaginary component. */
};

/** By default show the equation using the variable x. */
static char variable = 'x';

/** Check that the coefficient exists. */
#define check_coeff(coeff) \
if (optind >= argc) { \
fprintf(stderr, "Missing coefficient '" coeff "'\n"); \
print_usage(); \
exit(EXIT_FAILURE); \
}

void print_usage(void);
void print_complex(struct complex_t *c);
void quadratic_formula(struct quadratic_t *poly, struct complex_t *z0, struct complex_t *z1);

int main(int argc, char **argv) {

/* Parse options. */
int c;
while ((c = getopt(argc, argv, ":hv:")) != -1) {
switch (c) {
case 'h':
print_usage();
exit(EXIT_SUCCESS);
case 'v':
variable = optarg[0];
break;
case ':':
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
print_usage();
exit(EXIT_FAILURE);
case '?':
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
print_usage();
exit(EXIT_FAILURE);
default:
print_usage();
exit(EXIT_FAILURE);
}
}

/* Parse all three coefficients. */
struct quadratic_t polynomial;

check_coeff("a");
polynomial.a = strtod(argv[optind], NULL);
optind++;

check_coeff("b");
polynomial.b = strtod(argv[optind], NULL);
optind++;

check_coeff("c");
polynomial.c = strtod(argv[optind], NULL);
optind++;

/** Plug coefficients into the quadratic formula and determine the zero. */
struct complex_t z0;
struct complex_t z1;
quadratic_formula(&polynomial, &z0, &z1);

/** Display results. */
printf("%lf%c^2 + %lf%c + %lf\n", polynomial.a, variable, polynomial.b, variable, polynomial.c);

// First zero
printf("x = ");
print_complex(&z0);
putchar('\n');

// Second zero
printf("x = ");
print_complex(&z1);
putchar('\n');

return EXIT_SUCCESS;
}

/**
* Performs the quadratic formula calculation to find two zeros for a polynomial.
* @param poly The polynomial to use for the calculation.
* @param z0 Where the first calculated zero of the polynomial will be stored.
* @param z1 Where the second calculated zero of the polynomial will be stored.
*/
void quadratic_formula(struct quadratic_t *poly, struct complex_t *z0, struct complex_t *z1) {

double discriminant = (poly->b * poly->b) - 4.0 * poly->a * poly->c;
double denominator = (2.0 * poly->a); // 2a term in denominator

// Non complex roots
if (discriminant >= 0.0) {
z0->re = (-poly->b + sqrt(discriminant)) / denominator;
z1->re = (-poly->b - sqrt(discriminant)) / denominator;
z0->im = 0.0;
z1->im = 0.0;
return;
}

// Both zeroes will have the same real component
z0->re = -poly->b / denominator;
z1->re = z0->re;

// Zeroes will have complementary imaginary components
z0->im = sqrt(-discriminant) / denominator;
z1->im = -z0->im;
}

/**
* Prints a complex number to stdout.
* @param c The complex number to print.
*/
void print_complex(struct complex_t *c) {

// Don't print the imaginary component if there is none
if (c->im == 0.0) {
printf("%lf", c->re);
return;
}

printf("%lf + %lfi", c->re, c->im);
}

/**
* Prints usage information about the command line program.
*/
void print_usage(void) {
puts("quadratic v" VERSION);
puts("MIT License | By Matteo Golin, 2024");
putchar('\n');
puts("DESCRIPTION:");
puts("\tFinds the zeroes of a quadratic polynomial in form ax^2 + bx + c.");
putchar('\n');
puts("USAGE:");
puts("\tquadratic [options] -- a b c");
puts("\tEnsure you include the '--' before the coefficients so negative numbers are properly parsed.");
putchar('\n');
puts("EXAMPLES:");
puts("\tquadratic -- 1 -10 16");
puts("\t1.000000x^2 + -10.000000x + 16.000000");
puts("\tx = 8.000000");
puts("\tx = 2.000000");
putchar('\n');
puts("\tquadratic -v y -- 1 -10 16");
puts("\t1.000000y^2 + 2.000000y + 3.000000");
puts("\tx = -1.000000 + 1.414214i");
puts("\tx = -1.000000 + -1.414214i");
putchar('\n');
puts("ARGUMENTS");
puts("\ta\tThe value of the a coefficient of the polynomial.");
puts("\tb\tThe value of the b coefficient of the polynomial.");
puts("\tc\tThe value of the c coefficient of the polynomial.");
putchar('\n');
puts("OPTIONS:");
puts("\tv\tThe variable to show as being solved for in the quadratic equation. Defaults to x.");
puts("\th\tPrints this help screen and exits.");
}

0 comments on commit d3318e0

Please sign in to comment.