Skip to content

Instantly share code, notes, and snippets.

@magical
Created June 7, 2012 07:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magical/2887201 to your computer and use it in GitHub Desktop.
Save magical/2887201 to your computer and use it in GitHub Desktop.
gcd and lcm tools
gcd(1)
======
:doctype: manpage
:man source: gcd
:man version: 0.1
NAME
----
gcd, lcm - compute greatest common divisor and least common multiple
SYNOPSIS
--------
[verse]
*gcd* ['n'...]
*lcm* ['n'...]
DESCRIPTION
-----------
*gcd*(1) computes the greatest common divisor of its arguments. *lcm*(1)
computes the least common multiple of its arguments. The result is printed
to `stdout`. With no arguments they print their respective identities, 0 and 1.
The greatest common divisor of a set of integers is the largest integer that
evenly divides into every member of the set.
The least common multiple of a set of integers is the smallest integer that is
evenly divisible by every member of the set.
The GNU multiple precision arithmetic library (GMP) is used to perform the
calculations.
EXAMPLES
--------
--------------------
% gcd 100 256
4
% lcm 100 256
6400
% gcd 3 100 256
1
% lcm 3 100 256
19200
% lcm 2 3 4 5 6 8 9
360
% gcd 360
360
% gcd
0
--------------------
BUGS
----
This is a multi-call binary. It will not function if it is renamed.
SEE ALSO
--------
*bc*(1), and the Info manual for *gmp*
/* gcc -o gcd gcd.c -lgmp -O2 -Wall -Wextra */
/* gcc -o lcm gcd.c -lgmp -O2 -Wall -Wextra */
/* Usage: gcd [n ...] */
/* Usage: lcm [n ...] */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gmp.h>
static void do_gcd(int argc, char *argv[], mpz_t r, mpz_t n)
{
int i;
mpz_set_ui(r, 0U);
for (i = 1; i < argc; i++) {
if (mpz_set_str(n, argv[i], 0) < 0) {
fprintf(stderr, "gcd: expected an integer: arg %d: %s\n", i, argv[i]);
exit(EXIT_FAILURE);
}
mpz_gcd(r, r, n);
}
}
static void do_lcm(int argc, char *argv[], mpz_t r, mpz_t n)
{
int i;
mpz_set_ui(r, 1U);
for (i = 1; i < argc; i++) {
if (mpz_set_str(n, argv[i], 0) < 0) {
fprintf(stderr, "lcm: expected an integer: arg %d: %s\n", i, argv[i]);
exit(EXIT_FAILURE);
}
mpz_lcm(r, r, n);
}
}
static void usage(void)
{
fprintf(stderr, "Usage: gcd [n ...]\n");
fprintf(stderr, "Usage: lcm [n ...]\n");
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
char *basename;
mpz_t r, n;
mpz_init(r);
mpz_init(n);
if (argc < 1) {
usage();
}
basename = strrchr(argv[0], '/');
if (basename == NULL) {
basename = argv[0];
} else {
basename++;
}
if (strcmp(basename, "gcd") == 0) {
do_gcd(argc, argv, r, n);
} else if (strcmp(basename, "lcm") == 0) {
do_lcm(argc, argv, r, n);
} else {
usage();
}
if (mpz_out_str(stdout, 10, r) == 0) {
return EXIT_FAILURE;
}
printf("\n");
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment