Logo Search packages:      
Sourcecode: xabacus version File versions  Download package

AbacusM.c

/*
 * @(#)AbacusM.c
 *
 * Copyright 1994 - 2009  David A. Bagley, bagleyd@tux.org
 *
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of the author not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 *
 * This program is distributed in the hope that it will be "useful",
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

/*
 * AbacusM(ath) handles the string mathematics for the xabacus.
 * Whenever possible the mathematics is done using strings.
 * (Roman math is also done here and is limited by definition.)
 * I use long long when I can not figure out how to do it by strings,
 * as in Display Base.
 */

#include "AbacusP.h"

#define LONGEST_ROMANNUMERAL "mmmdccclxxxvMMMDCCCLXXXVIII" /* 3,888,888 */
#define MAX_ROMAN_NUMERAL 3999999
#define MAX_ROMAN_DIGIT 1000000
#define ROMANFRACTIONBASE 12
#define MAX_OLDROMAN 9

static char roman[] =
{
      'I', 'V', 'X', 'L', 'C', 'D', 'M',
           'v', 'x', 'l', 'c', 'd', 'm'
};
static char oldRoman[][MAX_OLDROMAN] = {
      "I", "V",     "X",    "L",       "(",    "I)", "(I)",
         "I))", "((I))", "I)))", "(((I)))", "I))))", "|x|"
};
/*
Here we have lower case to represent the letters with bars on top.
Pardon the non-standard notation (case historically was ignored).
Think of it as room to add the line by hand... :)
_
V = v,
_
X = x, etc
It has been suggested to put more bars on top for bigger numbers
but there is no recorded usage of a larger Roman numeral in
Roman times.
An older notation for Roman numerals was represented thus:
( = C, I) = D, (I) = M, I)) = v, ((I)) = x, I))) = l, (((I))) = c,
 _
|X| = m (here for simplicity of display, just displayed as |x| ).
Fractions
12 ounces (uncia) in a as
S = 1/2 ounce
) = 1/4 ounce
Z = 1/12 ounce
*/

#define MAX_TWELFTH 9
#define MAX_SUBTWELFTH 18
#define MAX_SUBEIGHTH 18
#define MAX_ROMANFRACT 36 /* MAX_TWELFTH+MAX_SUBTWELFTH+strlen(HALF_UNCIA) */
#define MAX_ROMANLEN 28 /* strlen(LONGEST_ROMANNUMERAL) */
#define MAX_ROMAN (MAX_ROMANFRACT+MAX_ROMANLEN)

/* Fractions of twelfths had these names 0/12 - 12/12 */
static char twelfthStrings[][MAX_TWELFTH] = {
      "", "uncia", "sextans", "quadrans",
      "triens", "quincunx", "semis", "septunx",
      "bes", "dodrans", "dextans", "deunix",
      "as"};
static char twelfthGlyphs[][5] = {
      "", "-", "=", "=-",
      "==", "=-=", "S", "S-",
      "S=", "S=-", "S==", "S=-=",
      "|"};

#define HALF_UNCIA "semuncia" /* E, (actually a Greek letter sigma) */
#define ONEANDAHALF_UNCIA "sescuncia" /* E- */
static char halftwelfthStrings[][10] = {
      HALF_UNCIA, ONEANDAHALF_UNCIA};
static char halftwelfthGlyphs[][3] = {
      "E", "E-"};

/* Fractions of Uncia had these names, took shortest variant */
#define TWELFTH_UNCIA "semisextula" /* z (actually, a "Z" with a "-" through
  the middle) AKA dimidia sextula, dimidio sextula */
#define SIXTH_UNCIA "sextula" /* Z */
#define QUARTER_UNCIA "sicilicus" /* Q (actually a backwards C but confusing
  with ancient Roman numerals) */
#define THIRD_UNCIA "duella" /* u (actually a Greek letter mu), AKA
  binae sextulae */
#define FIVETWELFTHS_UNCIA "sicilicus sextula" /* not sure if this is best
  representation */
#define EIGHTH_UNCIA "drachma"
#define THREEEIGHTHS_UNCIA "sicilicus drachma" /* not sure if this is best
  representation */
/* Combining fractions (not sure how this was done in practice
   but this seems reasonable). Combine with the representation
   for HALF_UNCIA or ONEANDAHALF_UNCIA as required. */
static char subtwelfthStrings[][MAX_SUBTWELFTH] = {
      "", TWELFTH_UNCIA, SIXTH_UNCIA,
      QUARTER_UNCIA, THIRD_UNCIA, FIVETWELFTHS_UNCIA};
static char subeighthStrings[][MAX_SUBEIGHTH] = {
      "", EIGHTH_UNCIA, QUARTER_UNCIA, THREEEIGHTHS_UNCIA};
static char subtwelfthGlyphs[][3] = {
      "", "z", "Z",
      "Q", "u", "QZ"};
static char subeighthGlyphs[][3] = {
      "", "t", "Q", "Qt"};

int
char2Int(char character)
{
      int charValue = character;

      if (charValue >= '0' && charValue <= '9') {
            charValue += 0 - '0';
      /* ASCII or EBCDIC */
      } else if (charValue >= 'a' && charValue <= 'i') {
            charValue += 10 - 'a';
      } else if (charValue >= 'j' && charValue <= 'r') {
            charValue += 19 - 'j';
      } else if (charValue >= 's' && charValue <= 'z') {
            charValue += 28 - 's';
      } else if (charValue >= 'A' && charValue <= 'I') {
            charValue += 10 - 'A';
      } else if (charValue >= 'J' && charValue <= 'R') {
            charValue += 19 - 'J';
      } else if (charValue >= 'S' && charValue <= 'Z') {
            charValue += 28 - 'S';
      } else
            charValue = 36;
      return charValue;
}

char
int2Char(int digit)
{
      char charValue = (char) digit;

      charValue += '0';
      /* ASCII or EBCDIC */
      if (charValue > '9' || charValue < '0') {
            charValue += ('A' - '9' - 1);
            if (charValue > 'I')
                  charValue += ('J' - 'I' - 1);
            if (charValue > 'R')
                  charValue += ('S' - 'R' - 1);
      }
      return charValue;
}

static int
int2String(char *buf, LONG number, int base, Boolean negative)
{
      int digit, last, position = 0, i;
      LONG mult = 1, remain = number;

      last = 1;
      while (mult * base <= remain) {
            mult *= base;
            last++;
            if (mult * base < mult) {
                  buf[0] = '0';
                  buf[1] = '\0';
                  return 2;
            }
      }
      if (negative) {
            buf[position] = '-';
            position++;
      }
      for (i = 0; i < last; i++) {
            digit = (int) (remain / mult);
            remain -= mult * digit;
            buf[position] = int2Char(digit);
            mult /= base;
            if (mult == 0 && i != last - 1) {
                  buf[0] = '0';
                  buf[1] = '\0';
                  return 2;
            }
            position++;
      }
      buf[position] = '\0';
      return last;
}

static int
flt2String(char *buf, LONG number, int abacusBase, int base, int places,
            int decimalPosition)
{
      int position = 0, digit;
      double mult = 1.0 / base;
      long divisor = base;
      double fraction = number;

      for (position = 0; position < places; position++) {
            fraction /= abacusBase;
      }
      for (position = 0; position < decimalPosition; position++) {
            digit = (int) (fraction * divisor);
            fraction -= mult * digit;
            buf[position] = int2Char(digit);
            mult /= base;
            divisor *= base;
            if (mult == 0 && position != places - 1) {
                  buf[0] = '\0';
                  return 0;
            }
      }
      buf[position] = '\0';
      for (digit = position - 1; digit > 0; digit--) {
            if (buf[digit] == '0')
                  buf[digit] = '\0';
            else
                  break;
      }
      return places;
}

#if 0
int
string2Int(char *buf, int base, char decimalPoint)
{
      int digit, position = 0, value = 0, last;

      if (buf[position] == '-') {
            return 0;
      }
      last = strlen(buf);
      for (; position < last; position++) {
            if (buf[position] == decimalPoint) {
                  break;
            }
            digit = char2Int(buf[position]);
            value = value * base + digit;
            if (value >= ((base >= 8) ? base / 2 - 1 : base) *
                        base * base * base * base * base * base)
                  return 0;
      }
      return value;
}
#endif

#ifndef MAX_INT
#define MAX_INT 9223372036854775807LL
#endif
/* Try not to use since this restricts the size of abacus. */
LONG
multPower(int m, int x, int n)
{     /* raise x to the nth power where m, x, n >= 0 */
      int i;
      LONG p = 1;
      LONG overflow;

      if (m == 0 || x == 0)
            return 0;
      overflow = MAX_INT / x;
      for (i = 1; i <= n; ++i) {
            if (p > overflow)
                  return -1;
            p *= ((LONG) x);
      }
      overflow = MAX_INT / m;
      if (p > overflow)
            return -1;
      return (p * m);
}

/* This is fast for small i. */
int
rootInt(int i, int n)
{
      int j = 0, k;
      int absI = (i >= 0) ? i : -i;
      int prod;

      if (n < 0 || i == 0 || (n % 2 == 0 && i < 0))
            return 0;
      if (n == 1)
            return i;
      absI = (i >= 0) ? i : -i;
      do {
            prod = 1;
            j++;
            for (k = 0; k < n; k++)
                  prod *= j;
      } while (prod <= absI);
      return (i == absI) ? (j - 1) : (1 - j);
}

void
dividePieces(char *buf, int base, int pieces, int mult, int places,
            char decimalPoint)
{
      int position, digit, inter;

#ifdef DEBUG
      (void) printf("dividePieces: base %d, pieces %d, mult %d, places %d\n",
            base, pieces, mult, places);
#endif
      digit = mult / pieces;
      inter = mult % pieces;
      (void) sprintf(buf, "%1d%c", digit, decimalPoint);
      for (position = 2; position < places;) {
            digit = (inter * base) / pieces;
            inter = (inter * base) % pieces;
            buf[position] = int2Char(digit);
            position++;
            if (inter == 0)
                  break;
      }
      buf[position] = '\0';
#ifdef DEBUG
      (void) printf("dividePieces: buf %s\n", buf);
#endif
}

void
shiftDecimal(char *buf, char *aBuf, int shift, int place, char decimalPoint)
{
      int size = strlen(aBuf);
      int loc = 0, i = 0, integerDigits;

#ifdef DEBUG
      (void) printf("shiftDecimal: aBuf %s, shift %d, place %d\n",
            aBuf, shift, place);
#endif
      while (aBuf[i] != decimalPoint && i < size) {
            buf[i] = aBuf[i];
            i++;
      }
      integerDigits = i;
      buf[i] = aBuf[i];
      loc = i;
      i++;
      while (i - 1 < place + integerDigits && i < size) {
            buf[i] = aBuf[i];
            i++;
      }
      loc = i - 1;
      if (shift > 0) {
            /* shift right */
            for (i = place + 2; i < shift + place + 2; i++)
                  buf[i] = '0';
      } else {
            /* shift left */
            loc -= shift;
      }
      while (loc < size - 1) {
            loc++;
            buf[i] = aBuf[loc];
            i++;
      }
      buf[i] = '\0';
#ifdef DEBUG
      (void) printf("shiftDecimal: buf %s\n", buf);
#endif
}

/* 2nd grade math made hard */
/* May disregard sign if different */
void
addStrings(char *buf, char *aBuf, char *bBuf, int base, char decimalPoint)
{
      int aEnd = strlen(aBuf), bEnd = strlen(bBuf); /* zeros included */
      int aDecimal = aEnd, bDecimal = bEnd;
      int aSign = ((aBuf[0] == '-') ? 1 : 0);
      int bSign = ((bBuf[0] == '-') ? 1 : 0);
      int i, carry = 0, digit;

#ifdef DEBUG
      (void) printf("addStrings: aBuf %s, bBuf %s, base %d\n",
            aBuf, bBuf, base);
#endif
      for (i = 0; i < aEnd; i++) {
            if (aBuf[i] == decimalPoint && aDecimal == aEnd) {
                  aDecimal = i;
                  break;
            }
      }
      for (i = 0; i < bEnd; i++) {
            if (bBuf[i] == decimalPoint && bDecimal == bEnd) {
                  bDecimal = i;
                  break;
            }
      }
      if (bEnd - bDecimal < aEnd - aDecimal) {
            for (i = 0; i < aEnd - bEnd - aDecimal + bDecimal; i++)
                  bBuf[bEnd + i] = '0';
            bEnd += i;
            bBuf[bEnd] = '\0';
      }
      if (bEnd - bDecimal > aEnd - aDecimal) {
            for (i = 0; i < bEnd - aEnd - bDecimal + aDecimal; i++)
                  aBuf[aEnd + i] = '0';
            aEnd += i;
            aBuf[aEnd] = '\0';
      }
      if (aDecimal + aSign >= bDecimal + bSign) {
            for (i = aEnd - 1; i > aDecimal; i--) {
                  digit = char2Int(aBuf[i]) +
                        char2Int(bBuf[i - aEnd + bEnd]) + carry;
                  aBuf[i] = int2Char(digit % base);
                  carry = digit / base;
            }
            for (i = aDecimal - 1; i >= aSign; i--) {
                  digit = char2Int(aBuf[i]) +
                        ((i - aEnd + bEnd >= bSign) ?
                        char2Int(bBuf[i - aEnd + bEnd]) : 0) + carry;
                  aBuf[i] = int2Char(digit % base);
                  carry = digit / base;
            }
            if (aSign == 1) {
                  buf[0] = '-';
                  buf[1] = '\0';
            }
            if (carry > 0) {
                  buf[aSign] = (char) (carry + '0');
                  (void) strcpy(&buf[aSign + 1], &aBuf[aSign]);
            } else
                  (void) strcpy(buf, aBuf);
      } else {
            for (i = bEnd - 1; i > bDecimal; i--) {
                  digit = char2Int(bBuf[i]) +
                        char2Int(aBuf[i - bEnd + aEnd]) + carry;
                  bBuf[i] = int2Char(digit % base);
                  carry = digit / base;
            }
            for (i = bDecimal - 1; i >= bSign; i--) {
                  digit = char2Int(bBuf[i]) +
                        ((i - bEnd + aEnd >= aSign) ?
                        char2Int(aBuf[i - bEnd + aEnd]) : 0) + carry;
                  bBuf[i] = int2Char(digit % base);
                  carry = digit / base;
            }
            if (bSign == 1) {
                  buf[0] = '-';
                  buf[1] = '\0';
            }
            if (carry > 0) {
                  buf[bSign] = (char) (carry + '0');
                  (void) strcpy(&buf[bSign + 1], &bBuf[bSign]);
            } else
                  (void) strcpy(buf, bBuf);
      }
      i = strlen(buf) - 1;
      while (buf[i] == '0' && buf[i - 1] != decimalPoint)
            i--;
      buf[i + 1] = '\0';
#ifdef DEBUG
      (void) printf("addStrings: buf %s\n", buf);
#endif
}

void
convertString(char * buf, char * inbuf, int base, int displayBase,
            int decimalPosition,
            int anomaly, int shiftAnomaly, Boolean carryAnomaly,
            int anomalySq, int shiftAnomalySq, Boolean carryAnomalySq,
            char decimalPoint)
{
      char fltbuf[256];
      int i, last, place = -1, decimalPlace, decimalPointPlace, mult;
      Boolean negative, gotDecimal = False;
      LONG intPart = 0, floatPart = 0, tmpPower;

#ifdef DEBUG
      (void) printf("convertString: inbuf %s\n", inbuf);
#endif
      last = strlen(inbuf);
      negative = (inbuf[0] == '-');
      for (i = (negative) ? 1 : 0; i < last; i++) {
            if (inbuf[i] == decimalPoint) {
                  place = i - 1 - ((negative) ? 1 : 0);
                  break;
            }
      }
      if (place == -1)
            place = last - 1 - ((negative) ? 1 : 0);
      decimalPlace = place;
      decimalPointPlace = last - 2 - ((negative) ? 1 : 0) - place;
      for (i = (negative) ? 1 : 0; i < last; i++) {
            if (inbuf[i] == decimalPoint) {
                  gotDecimal = True;
                  place = last - decimalPlace - 2 - ((negative) ? 1 : 0);
                  floatPart = 0;
                  place--;
            } else if (gotDecimal) {
                  mult = char2Int(inbuf[i]);
                  tmpPower = multPower(mult, base, place);
                  if (tmpPower < 0) {
                        floatPart = 0;
                        break;
                  }
                  floatPart += tmpPower;
                  place--;
            } else {
                  mult = char2Int(inbuf[i]);
                  if (place >= shiftAnomaly && anomaly != 0) {
                    if (place >= shiftAnomaly + shiftAnomalySq &&
                                    anomalySq != 0) {
                      tmpPower = multPower(mult * (base - anomaly) * (base - anomalySq),
                        base, place - 2);
                      if (tmpPower < 0 || intPart > MAX_INT - tmpPower) {
                        intPart = 0;
                        floatPart = 0;
                        break;
                      }
                      intPart += tmpPower;
                      if (carryAnomalySq &&
                        place == shiftAnomaly + shiftAnomalySq) {
                        tmpPower = multPower((base - anomaly) * anomalySq,

                        base, shiftAnomaly + shiftAnomalySq - 2);
                        if (tmpPower < 0 || intPart > MAX_INT - tmpPower) {
                        intPart = 0;
                        floatPart = 0;
                        break;
                        }
                        intPart += tmpPower;
                      }
                    } else {
                      tmpPower = multPower(mult * (base - anomaly), base,
                        place - 1);
                      if (tmpPower < 0 || intPart > MAX_INT - tmpPower) {
                        intPart = 0;
                        floatPart = 0;
                        break;
                      }
                      intPart += tmpPower;
                      if (carryAnomaly && place == shiftAnomaly) {
                        tmpPower = multPower(anomaly, base,
                        shiftAnomaly - 1);
                        if (tmpPower < 0 || intPart > MAX_INT - tmpPower) {
                        intPart = 0;
                        floatPart = 0;
                        break;
                        }
                        intPart += tmpPower;
                      }
                    }
                  } else {
                    tmpPower = multPower(mult, base, place);
                    if (tmpPower < 0 || intPart > MAX_INT - tmpPower) {
                      intPart = 0;
                      floatPart = 0;
                      break;
                    }
                    intPart += tmpPower;
                  }
                  place--;
            }
      }
      (void) int2String(buf, intPart, displayBase, negative);
      (void) flt2String(fltbuf, floatPart, base, displayBase,
            decimalPointPlace, decimalPosition);
      (void) sprintf(buf, "%s.%s", buf, fltbuf);
#ifdef DEBUG
      (void) printf("convertString: outbuf %s\n", buf);
#endif
}

int
sizeofRoman(int base, Boolean romanNumerals, Boolean ancientRoman)
{
      int romanWidth;

      if (!romanNumerals)
            return 0;
      romanWidth = ((base < 8) ? base : base / 2 - 1) *
            ((sizeof(roman) + 1) / 2);
      romanWidth *= ((ancientRoman) ? 6 : 1);
      return romanWidth + 12 + MAX_ROMANFRACT;
}

static void
romanFraction(char *buf, int base, int number, int subnumber,
            int subbase, Boolean latin)
{
      Boolean gotFraction = False;
      int halfBase = subbase / 2;
      int fraction = number, subfraction = subnumber;

      fraction %= base;
      if (fraction == 1 && subfraction >= halfBase) {
            subfraction -= halfBase;
            if (latin) {
                  (void) strcat(buf, halftwelfthStrings[1]);
                  gotFraction = True;
            } else {
                  (void) strcat(buf, halftwelfthGlyphs[1]);
            }
      } else if (fraction > 0) {
            if (latin) {
                  (void) strcat(buf, twelfthStrings[fraction *
                        ROMANFRACTIONBASE / base]);
                  gotFraction = True;
            } else {
                  (void) strcat(buf, twelfthGlyphs[fraction *
                        ROMANFRACTIONBASE / base]);
            }
      }
      if (subfraction >= halfBase) {
            subfraction -= halfBase;
            if (latin) {
                  if (gotFraction)
                        (void) strcat(buf, " ");
                  gotFraction = True;
                  (void) strcat(buf, halftwelfthStrings[0]);
            } else {
                  (void) strcat(buf, halftwelfthGlyphs[0]);
            }
      }
      if (subfraction != 0) {
            if (latin) {
                  if (gotFraction)
                        (void) strcat(buf, " ");
                  if (subbase == 8)
                        (void) strcat(buf, subeighthStrings[subfraction]);
                  else
                        (void) strcat(buf, subtwelfthStrings[subfraction]);
            } else {
                  if (subbase == 8)
                        (void) strcat(buf, subeighthGlyphs[subfraction]);
                  else
                        (void) strcat(buf, subtwelfthGlyphs[subfraction]);
            }
      }
}

static int
append(char *buf, int position, int place, Boolean ancient)
{
      if (ancient) {
            buf[position] = '\0';
            (void) strcat(&buf[position], oldRoman[place]);
            return (int) strlen(oldRoman[place]);
      } else {
            buf[position] = roman[place];
            return 1;
      }
}

int
string2Roman(char *buf, char *inbuf, int base,
            int pieces, int number, int subnumber, int subbase,
            char decimalPoint, Boolean ancientRoman, Boolean latin)
{
      int i = 0, position = 0, digit, last, j;
      int loga = (sizeof(roman) + 1) / 2;

      buf[position] = '[';
      position++;
      if (inbuf[i] == '-') {
            buf[position] = ']';
            position++;
            buf[position] = '\0';
            return 0;
      }
      last = (int) strlen(inbuf);
      for (i = 0; i < last; i++) {
            if (inbuf[i] == decimalPoint) {
                  break;
            }
      }
      last = i;
      i = 0;
      digit = char2Int(inbuf[i]);
      if (last > loga || (last == loga &&
                  digit >= ((base >= 8) ? base / 2 - 1 : base))) {
            buf[position] = '?';
            position++;
            buf[position] = ']';
            position++;
            buf[position] = '\0';
            return 0;
      }
      for (i = 0; i < last; i++) {
            int romanChar = 2 * (last - i) - 1;

            digit = char2Int(inbuf[i]);
            /* IX */
            if (!ancientRoman && digit >= base + 1 - base / 4 &&
                        base >= 8) {
                  for (j = 0; j < base - digit; j++) {
                        position += append(buf, position,
                              romanChar - 1, ancientRoman);
                  }
                  position += append(buf, position,
                        romanChar + 1, ancientRoman);
            /* VI */
            } else if (digit >= (base + 1) / 2 && base >= 4) {
                  position += append(buf, position,
                        romanChar, ancientRoman);
                  digit = digit - (base + 1) / 2;
                  while (digit > 0) {
                        position += append(buf, position,
                              romanChar - 1, ancientRoman);
                        digit--;
                  }
            /* IV */
            } else if (!ancientRoman && digit >= (base + 1) / 2 + 1 - base / 4 &&
                        base >= 8) {
                  for (j = 0; j < (base + 1) / 2 - digit; j++) {
                        position += append(buf, position,
                              romanChar - 1, ancientRoman);
                  }
                  position += append(buf, position,
                        romanChar, ancientRoman);
            /* I */
            } else {
                  while (digit > 0) {
                        position += append(buf, position,
                              romanChar - 1, ancientRoman);
                        digit--;
                  }
            }
      }
      buf[position] = '\0';
      if (pieces > 0 && ROMANFRACTIONBASE % pieces == 0) {
            char fractbuf[MAX_ROMANFRACT] = "";
            int subfraction = subnumber;

            if (pieces != ROMANFRACTIONBASE)
                  subfraction = 0; /* words not scalable */
            if (latin && position > 1 && (number != 0 || subfraction != 0))
                  (void) strcat(buf, " ");
            romanFraction(fractbuf, pieces, number, subfraction,
                  subbase, latin);
            (void) strcat(buf, fractbuf);
      }
      (void) strcat(buf, "]");
      return 0;
}

#if 0
int
int2Roman(char *buf, int arabic)
{
      int i = 0, position = 0, digit;
      int loga = (sizeof(roman) + 1) / 2;
      int place = MAX_ROMAN_DIGIT;
      int base = DEFAULT_BASE;
      int remain = arabic;

      buf[position] = '[';
      position++;
      if (remain < 0 || remain > MAX_ROMAN_NUMERAL) {
            buf[position] = ']';
            position++;
            buf[position] = '\0';
            return 0;
      }
      for (i = 0; i < loga; i++) {
            digit = remain / place;
            remain -= digit * place;
            if (digit >= base - 1) {
                  buf[position] = roman[2 * (loga - i - 1)];
                  position++;
                  buf[position] = roman[2 * (loga - i)];
                  position++;
            } else if (digit >= (base + 1) / 2) {
                  buf[position] = roman[2 * (loga - i) - 1];
                  position++;
                  digit = digit - (base + 1) / 2;
                  while (digit > 0) {
                        buf[position] = roman[2 * (loga - i - 1)];
                        position++;
                        digit--;
                  }
            } else if (digit >= (base + 1) / 2 - 1) {
                  buf[position] = roman[2 * (loga - i - 1)];
                  position++;
                  buf[position] = roman[2 * (loga - i) - 1];
                  position++;
            } else {
                  while (digit > 0) {
                        buf[position] = roman[2 * (loga - i - 1)];
                        position++;
                        digit--;
                  }
            }
            place /= base;
      }
      buf[position] = ']';
      position++;
      buf[position] = '\0';
      return 0;
}
#endif

void string2Group(char *buf, char *inbuf, int groupSize, char decimalPoint,
            char groupSeparator) {
      int i, j, len;

      for (i = 0; i < (int) strlen(inbuf); i++) {
            if (inbuf[i] == ' ' || inbuf[i] == decimalPoint) {
                  break;
            }
      }
      len = i;
      j = 0;
      if (inbuf[j] == '-' || inbuf[j] == '+') {
            buf[j] = inbuf[0];
            j = 1;
      }
      for (i = j; i < len - 1; i++) {
            buf[j] = inbuf[i];
            if ((len - i + groupSize - 1) % groupSize == 0) {
                  j++;
                  buf[j] = groupSeparator;
            }
            j++;
      }
      buf[j] = '\0';
      (void) sprintf(buf, "%s%s", buf, &inbuf[len - 1]);
}

int
convertBaseToBottom(int base)
{
      int j;

      for (j = rootInt(base, 2); j > 1; j--) {
            if (base % j == 0) {
                  return (base / j);
            }
      }
      return base;
}

Generated by  Doxygen 1.6.0   Back to index