Skip to content

Instantly share code, notes, and snippets.

@niconii
Created August 17, 2018 00:42
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 niconii/32898263d893905853d8f6de742b6033 to your computer and use it in GitHub Desktop.
Save niconii/32898263d893905853d8f6de742b6033 to your computer and use it in GitHub Desktop.
Forth number formatting, ported to C
#include <stdio.h>
#include <string.h>
#define NFMT_BUF_LEN 32
const char nfmt_set[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char nfmt_base;
char nfmt_buf[NFMT_BUF_LEN+1] = {0};
char* nfmt_ptr;
// equivalent to BASE <# in Forth
void nfmt_init(char base) {
nfmt_base = base;
nfmt_buf[NFMT_BUF_LEN] = '\0';
nfmt_ptr = &nfmt_buf[NFMT_BUF_LEN];
}
// equivalent to HOLD in Forth
void nfmt_hold(char c) {
--nfmt_ptr;
*nfmt_ptr = c;
}
// equivalent to HOLDS in Forth
void nfmt_holds(char* c) {
int len = strlen(c);
nfmt_ptr -= len;
memcpy(nfmt_ptr, c, len);
}
// equivalent to # in Forth
void nfmt_digit(unsigned long* n) {
char digit = nfmt_set[*n % nfmt_base];
*n /= nfmt_base;
nfmt_hold(digit);
}
// equivalent to #S in Forth
void nfmt_digits(unsigned long* n) {
do {
nfmt_digit(n);
} while (*n != 0);
}
// equivalent to #> in Forth
char* nfmt_end() {
return nfmt_ptr;
}
void thousands(unsigned long* n) {
while (*n > 999) {
nfmt_digit(n);
nfmt_digit(n);
nfmt_digit(n);
nfmt_hold(',');
}
nfmt_digits(n);
}
char* number(long n) {
char sign = 0;
if (n < 0) {
sign = 1;
n = -n;
}
nfmt_init(10);
thousands(&n);
if (sign) nfmt_hold('-');
return nfmt_end();
}
char* cents(long n) {
char sign = 0;
if (n < 0) {
sign = 1;
n = -n;
}
nfmt_init(10);
if (sign) nfmt_hold(')'); // accounting-style negative numbers
nfmt_digit(&n);
nfmt_digit(&n);
nfmt_hold('.');
thousands(&n);
nfmt_hold('$');
if (sign) nfmt_hold('(');
return nfmt_end();
}
char* hex(unsigned long n) {
nfmt_init(16);
nfmt_digits(&n);
nfmt_holds("0x");
return nfmt_end();
}
int main() {
puts(number(25252)); // 25,252
puts(number(-500)); // -500
puts(cents(1234567890)); // $12,345,678.90
puts(cents(-200000)); // ($2,000.00)
puts(hex(32768)); // 0x8000
puts(hex(-1)); // 0xFFFFFFFFFFFFFFFF
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment