nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 07:10



Reply to topic  [ 9 posts ] 
Balanced ternary arithmetics 
Author Message
Retired

Joined: 03 Aug 2003 22:37
Posts: 1474
Location: Moscow
Reply with quote
Due to rising interests to implementation of arithmetics operations in balanced ternary system I decided to publish some source code, that was written by Mr. James Allwright, since his web-site - http://perun.hscs.wmin.ac.uk/~jra/ternary/ - is no longer available. The code is in C language and shows how to perform some elementary operations.

Code:
/* Package of routines for arithmetic in balanced ternary */
/* Numbers are held as an array of size lena stored least */
/* significant byte first */

/* Developed by James Allwright,                   */
/* Department of Electronics and Computer Science, */
/* University of Southampton, UK                   */

#define MAXLEN 50

static int plus_one[MAXLEN] = {1};
static int len_plus_one = 1;

add(lena, lenb, lenc, a, b, c)
/* c = a + b */
/* add together 2 numbers in balanced ternary */
int *lena, *lenb, *lenc;
int a[MAXLEN], b[MAXLEN], c[MAXLEN];
{
  int carry, i;

  zero(lenc, c);
  carry = 0;
  i = 0;
  while ((carry != 0) || (i < *lena) || (i < *lenb)) {
    c[i] = carry;
    if (i < *lena) {
      c[i] = c[i] + a[i];
    };
    if (i < *lenb) {
      c[i] = c[i] + b[i];
    };
    carry = 0;
    if (c[i] > 1) {
      c[i] = c[i] - 3;
      carry = 1;
    };
    if (c[i] < -1) {
      c[i] = c[i] + 3;
      carry = -1;
    };
    i = i + 1;
    if ((i >= MAXLEN) && (carry != 0)) {
      printf("Overflow error!\n");
      exit(-1);
    };
  };
  *lenc = i+1;
  while ((*lenc > 0) && (c[*lenc-1] == 0)) {
    *lenc = *lenc -1;
  };
};

negate(lena, a)
/* a = -a */
int *lena;
int a[MAXLEN];
{
  int i;

  for (i=0; i < *lena; i++) {
    a[i] = -a[i];
  };
};

neg(lena, lenb, a, b)
/* b = -a */
int *lena, *lenb;
int a[MAXLEN], b[MAXLEN];
{
  int i;

  for (i=0; i < *lena; i++) {
    b[i] = -a[i];
  };
  *lenb = *lena;
};

sub(lena, lenb, lenc, a, b, c)
/* c = a - b */
/* subtract numbers in balanced ternary */
/* using negate and add */
int *lena, *lenb, *lenc;
int a[MAXLEN], b[MAXLEN], c[MAXLEN];
{
  int lent;
  int temp[MAXLEN];
  /* temp = -b */
  neg(lenb, &lent, b, temp);
  add(lena, &lent, lenc, a, temp, c);
};

copy(lena, lenb, a, b)
/* copies a into b */
int *lena, *lenb;
int a[MAXLEN], b[MAXLEN];
{
  int i;

  for (i=0; i<*lena; i++) {
    b[i] = a[i];
  };
  *lenb = *lena;
};

zero(lena, a)
/* a = 0 */
/* sets a to zero */
int *lena;
int a[MAXLEN];
{
  int i;

  for (i=0; i<MAXLEN; i++) {
    a[i] = 0;
  };
  *lena = 0;
};

mshift(lena, a)
/* shift left one place (multiply by 3) */
int *lena;
int a[MAXLEN];
{
  int i;

  if (*lena >= MAXLEN ) {
    printf("Overflow error in mshift\n");
    exit(-1);
  };
  *lena = *lena + 1;
  for (i=*lena-1; i>0; i--) {
    a[i] = a[i-1];
  };
  a[0] = 0;
};

dshift(lena, a)
/* shift right one place (divide by 3) */
int *lena;
int a[MAXLEN];
{
  int i;

  if (*lena > 0) {
    *lena = *lena - 1;
    for (i=0; i<*lena; i++) {
      a[i] = a[i+1];
    };
  };
};

mul(lena, lenb, lenc, a, b, c)
/* multiply together 2 numbers in balanced ternary */
int *lena, *lenb, *lenc;
int a[MAXLEN], b[MAXLEN], c[MAXLEN];
{
  int lend, lent;
  int d[MAXLEN], temp[MAXLEN];
  int i;

  zero(lenc, c);
  if (*lena + *lenb - 2 > MAXLEN) {
    printf("Result too large error in multiplication!\n");
    exit(1);
  };
  copy(lenb, &lend, b, d);
  for (i=0; i < *lena; i++) {
    if (a[i] == 1) {
      /* c = c + d */
      add(lenc, &lend, &lent, c, d, temp);
      copy(&lent, lenc, temp, c);
    };
    if (a[i] == -1) {
      /* c = c - d */
      sub(lenc, &lend, &lent, c, d, temp);
      copy(&lent, lenc, temp, c);
    };
    if (i < *lena-1) {
      mshift(&lend, d);
    };
  };
};

int compare(lena, lenb, a, b)
/*  used by div           */
/*  returns :             */
/*    1  if  |a| >  |b|   */
/*    0  if  |a| == |b|   */
/*   -1  if  |a| <  |b|   */

int *lena, *lenb;
int a[MAXLEN], b[MAXLEN];
{
  int signa, signb;
  int place;
 
  if (*lena > *lenb) {
    return(1);
  };
  if (*lena < *lenb) {
    return(-1);
  };
  /* get sign of a and b */
  signa = a[*lena-1];
  signb = b[*lenb-1];
  place = *lena - 1;
  while ((place >= 0) && (signa*a[place] == signb*b[place])) {
    place = place -1;
  };
  if (place == -1) {
    return(0);
  } else {
    if (signa*a[place] > signb*b[place]) {
      return(1);
    } else {
      return(-1);
    };
  };
};

div(lena_in, lenb_in, lenc, lena, a_in, b_in, c, a)
/*  divide numbers in balanced ternary  */
/*  calculates a_in / b_in, returning   */
/*  c = result, a = remainder           */
/*  algorithm is like decimaltoBT       */
/*  a and b are working copies of a_in and b_in */
int *lena_in, *lenb_in, *lenc, *lena;
int a_in[MAXLEN], b_in[MAXLEN], c[MAXLEN], a[MAXLEN];
{
  int lenb_store;
  int *lenb;
  int lent;
  int b[MAXLEN], temp[MAXLEN];
  int pos, digit;

  if (*lenb_in == 0) {
    printf("Division by zero error!\n");
    exit(1);
  };
  if (*lena_in == 0) {
    *lenc = 0;
    return;
  };
  copy(lena_in, lena, a_in, a); /* remainder starts as a */
  lenb = &lenb_store;
  copy(lenb_in, lenb, b_in, b); /* copy in b */
  pos = 0;
  digit = - 1;

  /* align b appropriately */
  while (*lenb < (*lena+1)) {
    mshift(lenb, b);
    pos = pos + 1;
  };
  while (*lenb > (*lena+1)) {
    dshift(lenb, b);
    pos = pos - 1;
  };
  if (pos >= 0) {
    *lenc = pos + 1; /* initial guess at length of result */
  } else {
    *lenc = 0;
  }

  while ((*lena > 0) && (pos >= 0)) {
    /* decide whether to try +b or -b */
    if (a[*lena - 1] == b[*lenb - 1]) {
      digit = - digit;
      /* b = -b */
      neg(lenb, &lent, b, temp);
      copy(&lent, lenb, temp, b);
    };
    /* temp = a + b */
    add(lena, lenb, &lent, a, b, temp);
    if (compare(lena, &lent, a, temp) == 1) {
      /* accept digit */
      /* a = temp */
      copy(&lent, lena, temp, a);
      c[pos] = digit;
    } else {
      /* don't accept digit */
      c[pos] = 0;
    };
    pos = pos - 1;
    dshift(lenb, b);
  };

  /* if we've reduced a to zero, fill in the remaining digits with 0 */
  while (pos >= 0) {
    c[pos] = 0;
    pos = pos - 1;
  };

  /* correct the length of the result */
  while ((*lenc > 0) && (c[*lenc-1] == 0)) {
    *lenc = *lenc - 1;
  };

  /* ensure that the remainder is the same sign as a_in */
  if (*lena > 0) { /* no problem if there is no remainder */
    if (a_in[*lena_in - 1] != a[*lena-1]) {
      if ((a_in[*lena_in - 1] == b_in[*lenb_in-1]) ) {
        /* a = a + b_in */
        add(lena, lenb_in, &lent, a, b_in, temp);
        copy(&lent, lena, temp, a);
        /* c = c - 1 */
        sub(lenc, &len_plus_one, &lent, c, plus_one, temp);
        copy(&lent, lenc, temp, c);
      } else {
        /* a = a - b_in */
        sub(lena, lenb_in, &lent, a, b_in, temp);
        copy(&lent, lena, temp, a);
        /* c = c + 1 */
        add(lenc, &len_plus_one, &lent, c, plus_one, temp);
        copy(&lent, lenc, temp, c);
      };
    };
  };
};

BTtodecimal(lena, a, result)
/* convert Balanced Ternary to decimal */
int *lena;
int a[MAXLEN];
int *result;
{
  int b, i;

  b = 1;
  *result = 0;
  for (i=0; i < (*lena); i++) {
    *result = *result + b * a[i];
    b = b * 3;
  };
};

int abs(a)
int a;
{
  if (a > 0) {
    return(a);
  } else {
    return(-a);
  };
};

decimaltoBT(lenr, result, value)
/* convert decimal to Balanced Ternary */
int *lenr;
int result[MAXLEN];
int value;
{
  int target, val, goal, pos;

  *lenr = 0;
  target = value;
  pos = 0;
  val = 1;
  goal  = 2 * target;
  if (goal < 0) {
    goal = -goal;
  };
  while ((val < goal) && (pos < MAXLEN)) {
    val = 3 * val;
    pos = pos + 1;
  };
  if (pos >= MAXLEN) {
    printf("Overflow error in decimaltoBT\n");
    exit(-1);
  };
  if ( target < 0) {
    val = -val;
  };
  while (pos >= 0) {
    if (abs(target-val) < abs(target)) {
      if (val > 0) {
        result[pos] = 1;
        target = target - val;
      } else {
        result[pos] = -1;
        target = target - val;
      };
      if (*lenr == 0) {
        *lenr = pos+1;
      };
    } else {
      result[pos] = 0;
    };
    val = val / 3;
    pos = pos - 1;
    /* make target and val the same sign */
    if ((target * val) < 0) {
      val = -val;
    };
  };
};

printnum(lena, a)
int *lena;
int a[MAXLEN];
{
  int i;

  for (i=*lena-1; i>=0; i--) {
    printf("(%d)", a[i]);
  };
  if (*lena == 0) printf("(0)");
};

main(argc, argv)
int argc;
char *argv[];
{
  int a[MAXLEN], b[MAXLEN], c[MAXLEN], rem[MAXLEN];
  int lena, lenb, lenc, lenrem;
  int i, answer;
  int t1, t2, t3;

  printf("Testing decimaltoBT and BTtodecimal.\n");
  for (i=0; i<100; i++) {
    t1 = (rand() % 1000) - 500;
    decimaltoBT(&lena, a, t1);
    BTtodecimal(&lena, a, &t3);
    if (t3 != t1) {
      printf("Error : %d has been converted to %d\n", t1, t3);
    };
  };
  printf("Testing add.\n");
  for (i=0; i<100; i++) {
    t1 = (rand() % 1000) - 500;
    t2 = (rand() % 1000) - 500;
    decimaltoBT(&lena, a, t1);
    decimaltoBT(&lenb, b, t2);
    add(&lena, &lenb, &lenc, a, b, c);
    BTtodecimal(&lenc, c, &t3);
    if (t3 != (t1+t2)) {
      printf("add gives %d + %d = %d\n", t1, t2, t3);
      printf("Error : answer should be %d\n", t1+t2);
    };
  };
  printf("Testing sub.\n");
  for (i=0; i<100; i++) {
    t1 = (rand() % 1000) - 500;
    t2 = (rand() % 1000) - 500;
    decimaltoBT(&lena, a, t1);
    decimaltoBT(&lenb, b, t2);
    sub(&lena, &lenb, &lenc, a, b, c);
    BTtodecimal(&lenc, c, &t3);
    if (t3 != (t1-t2)) {
      printf("add gives %d + %d = %d\n", t1, t2, t3);
      printf("Error : answer should be %d\n", t1-t2);
    };
  };
  printf("Testing mul.\n");
  for (i=0; i<100; i++) {
    t1 = (rand() % 10000) - 5000;
    t2 = (rand() % 10000) - 5000;
    decimaltoBT(&lena, a, t1);
    decimaltoBT(&lenb, b, t2);
    mul(&lena, &lenb, &lenc, a, b, c);
    BTtodecimal(&lenc, c, &t3);
    if (t3 != (t1*t2)) {
      printf("mul gives %d * %d = %d\n", t1, t2, t3);
      printf("Error : answer should be %d\n", t1*t2);
    };
  };
  printf("Testing div.\n");
  for (i=0; i<100; i++) {
    t1 = (rand() % 1000) - 500;
    t2 = (rand() % 50) - 25;
    if (t2 == 0) {
      t2 = 1;
    };
    decimaltoBT(&lena, a, t1);
    decimaltoBT(&lenb, b, t2);
    div(&lena, &lenb, &lenc, &lenrem, a, b, c, rem);
    BTtodecimal(&lenc, c, &t3);
    if (t3 != (t1/t2)) {
      printf("div gives %d / %d = %d\n", t1, t2, t3);
      printf("Error : answer should be %d\n", t1/t2);
    };
  };
};




13 Aug 2008 00:50
Profile
Retired

Joined: 03 Aug 2003 22:37
Posts: 1474
Location: Moscow
Reply with quote
Also on his site was a Java-based calculator to be used with balanced ternary numbers. Here is source code for it:

Code:
import java.awt.*;
import java.util.*;
import java.applet.Applet;

///* Developed by James Allwright,                   */
///* Department of Electronics and Computer Science, */
///* University of Southampton, UK                   */

public class Calculator extends Applet {
  stackbox thestack = new stackbox();
  keypad keys = new keypad(thestack);

  public void init() {
    Label label;
    int j;

//    label = new Label("Balanced Ternary Calculator", Label.CENTER);
//    add(label);
    add(keys);
    add(thestack);
  }

  public boolean handleEvent(Event e) {
    int j;

    if ((e.target == thestack.decimalbox) && (e.id == Event.ACTION_EVENT)) {
      thestack.fromdecimal();
    }
    return false;
  }

}

class keypad extends Panel {

  Button PlusOne, Zero, MinusOne, AC;
  Button Push, Pop;
  Button Add, Sub, Mul, Div;
  Button Decimal;
  Button Neg;
  stackbox astack;

  public keypad(stackbox thestack) {

    setLayout(new GridLayout(3, 4));
    astack = thestack;
    MinusOne = new Button("-1");
    Zero = new Button("0");
    PlusOne = new Button("+1");
    AC = new Button("AC");
    add(MinusOne);
    add(Zero);
    add(PlusOne);
    add(AC);
    Add = new Button("+");
    Sub = new Button("-");
    Mul = new Button("x");
    Div = new Button("/");
    add(Add);
    add(Sub);
    add(Mul);
    add(Div);
    Push = new Button("PUSH");
    Pop = new Button("POP");
    add(Push);
    add(Pop);
    Decimal = new Button("DEC");
    add(Decimal);
    Neg = new Button("NEG");
    add(Neg);
  }

  public boolean handleEvent(Event e) {
    int j;

    if (e.target == MinusOne) {
      astack.setdigit(-1);
    }
    if (e.target == Zero) {
      astack.setdigit(0);
    }
    if (e.target == PlusOne) {
      astack.setdigit(1);
    }
    if (e.target == AC) {
      astack.clear();
    }
    if (e.target == Push) {
      astack.push();
    }
    if (e.target == Pop) {
      astack.pop();
    }
    if (e.target == Add) {
      astack.add();
    }
    if (e.target == Sub) {
      astack.sub();
    }
    if (e.target == Mul) {
      astack.mul();
    }
    if (e.target == Div) {
      astack.div();
    }
    if (e.target == Decimal) {
      astack.todecimal();
    }
    if (e.target == Neg) {
      astack.neg();
    }
    return false;
  }

}

class stackbox extends Panel {
  int place = 0;
  BTnumber result = new BTnumber();
  BTnumber stack[] = new BTnumber[5];
  TextField stacktext[] = new TextField[5];
  TextField decimalbox;
  BTnumber plus_one = new BTnumber();
  boolean onresult = false;
  boolean overflow;

  stackbox() {
    int j;

    setLayout(new GridLayout(6, 1));
    for (j=4; j>=0; j--) {
      stack[j] = new BTnumber();
      stacktext[j] = new TextField("", stack[j].MAXLEN);
      add(stacktext[j]);
    }
    decimalbox = new TextField("", 11);
    add(decimalbox);
    refresh(place);
    plus_one.AddDigit(1);
  }

  void refresh(int n) {
    stacktext[n].setText(stack[n].textify());
  }

  void setzero(int n) {
    stack[n].zero();
    refresh(n);
  }

  void clear() {
    if (onresult) {
      error("");
      onresult = false;
      if (place < 4) {
        place = place + 1;
      }
    }
    setzero(place);
  }

  void setnull(int n) {
    stack[n].zero();
    stacktext[n].setText("");
  }

  void setdigit(int d) {
    if (onresult) {
      error("");
      onresult = false;
      if (place < 4) {
        place = place + 1;
      }
      setzero(place);
    }
    stack[place].AddDigit(d);
    refresh(place);
  }

  void error(String text) {
    decimalbox.setText(text);
  }

  boolean pre_binary_op() {
    error("");
    overflow = false;
    if (place > 0) {
      return true;
    } else {
      return false;
    }
  }

  void post_binary_op() {
    setnull(place);
    place = place -1;
    onresult = true;
    refresh(place);
  }

  void pop() {
    error("");
    stack[place].zero();
    setnull(place);
    if (place > 0) {
      place = place - 1;
      onresult = true;
      refresh(place);
    } else {
      onresult = false;
    }
  }

  void push() {
    onresult = true;
  }

  BTnumber addnum(BTnumber a, BTnumber b) {
  /* c = a + b */
  /* add together 2 numbers in balanced ternary */
    int carry, i, digit;
    BTnumber c = new BTnumber();
 
    carry = 0;
    i = 0;
    c.digit[i] = 0;
    while ((carry != 0) || (i < a.length) || (i < b.length)) {
      c.digit[i] = carry;
      if (i < a.length) {
        c.digit[i] = c.digit[i] + a.digit[i];
      }
      if (i < b.length) {
        c.digit[i] = c.digit[i] + b.digit[i];
      }
      carry = 0;
      if (c.digit[i] > 1) {
        c.digit[i] = c.digit[i] - 3;
        carry = 1;
      }
      if (c.digit[i] < -1) {
        c.digit[i] = c.digit[i] + 3;
        carry = -1;
      }
      i = i + 1;
      if ((i == c.MAXLEN) && (carry != 0)) {
        carry = 0;
        overflow = true;
      }
    }
    if (overflow) {
      c.zero();
      error("Overflow Error");
    } else {
      c.length = i;
      while ((c.length > 0) && (c.digit[c.length-1] == 0)) {
        c.length = c.length - 1;
      }
    }
    return c;
  }

  BTnumber subnum(BTnumber a, BTnumber b) {
    BTnumber t = new BTnumber();

    t.takevalue(b);
    t.negate();
    return addnum(a, t);
  }

  BTnumber mulnum(BTnumber a, BTnumber b)
  /* multiply together 2 numbers in balanced ternary */
  {
    BTnumber c = new BTnumber();
    BTnumber d = new BTnumber();
    int i;
 
    if ((a.length + b.length - 2) > a.MAXLEN) {
      error("Overflow Error");
      return c;
    }
    d.takevalue(b);
    for (i=0; i < a.length; i++) {
      if (a.digit[i] == 1) {
        /* c = c + d */
        c = addnum(c, d);
      }
      if (a.digit[i] == -1) {
        /* c = c - d */
        c = subnum(c, d);
      }
      if (i != a.length-1) {
        mshift(d);
      }
    }
    if (overflow) {
      c.zero();
      error("Overflow Error");
    }
    return c;
  }

  int compare(BTnumber a, BTnumber b)
  /*  used by div         */
  /*  returns :           */
  /*    1  if  a >  b     */
  /*    0  if  a == b     */
  /*   -1  if  a <  b     */
 
  {
    int signa, signb;
    int place;
   
    if (a.length > b.length) {
      return(1);
    }
    if (a.length < b.length) {
      return(-1);
    }
    /* get sign of a and b */
    signa = a.digit[a.length-1];
    signb = b.digit[b.length-1];
    place = a.length - 1;
    while ((place >= 0) && (signa*a.digit[place] == signb*b.digit[place])) {
      place = place -1;
    }
    if (place == -1) {
      return(0);
    } else {
      if (signa*a.digit[place] > signb*b.digit[place]) {
        return(1);
      } else {
        return(-1);
      }
    }
  }
 
  BTnumber divnum(BTnumber a_in, BTnumber b_in)
  /*  divide numbers in balanced ternary  */
  /*  calculates a_in / b_in, returning   */
  /*  c = result, a = remainder           */
  /*  algorithm is like decimaltoBT       */
  /*  a and b are working copies of a_in and b_in */
  {
    BTnumber a = new BTnumber();
    BTnumber b = new BTnumber();
    BTnumber c = new BTnumber();
    BTnumber temp;
    int pos, digit;
 
    if (b_in.length == 0) {
      error("Division by zero");
      return c;
    }
    if (a_in.length == a_in.MAXLEN) {
      error("Numerator too great");
      return c;
    }
    if (a_in.length == 0) {
      return c;
    }
    a.takevalue(a_in);
    b.takevalue(b_in);
    pos = 0;
    digit = - 1;
    /* align b appropriately */
    while (b.length < (a.length+1)) {
      mshift(b);
      pos = pos + 1;
    }
    while (b.length > (a.length+1)) {
      dshift(b);
      pos = pos - 1;
    }
    if (pos >= 0) {
      c.length = pos + 1; /* initial guess at length of result */
    }
 
    while ((a.length > 0) && (pos >= 0) && (b.length > 0)) {
      /* decide whether to try +b or -b */
      if (a.digit[a.length - 1] == b.digit[b.length - 1]) {
        digit = - digit;
        /* b = -b */
        b.negate();
      }
      /* temp = a + b */
      temp = addnum(a, b);
      if (compare(a, temp) == 1) {
        /* accept digit */
        /* a = temp */
        a = temp;
        c.digit[pos] = digit;
      } else {
        /* don't accept digit */
        c.digit[pos] = 0;
      }
      pos = pos - 1;
      dshift(b);
    }
    /* if we've reduced a to zero, fill in the remaining digits with 0 */
    while (pos >= 0) {
      c.digit[pos] = 0;
      pos = pos - 1;
    }
    /* correct the length of the result */
    while ((c.length > 0) && (c.digit[c.length-1] == 0)) {
      c.length = c.length - 1;
    }
    /* ensure that the remainder is the same sign as a_in */
    if (a.length > 0) { /* no problem if there is no remainder */
      if (a_in.digit[a_in.length - 1] != a.digit[a.length-1]) {
        if ((a_in.digit[a_in.length - 1] == b_in.digit[b_in.length-1]) ) {
          /* a = a + b_in */
          a = addnum(a, b_in);
          /* c = c - 1 */
          c = subnum(c, plus_one);
        } else {
          /* a = a - b_in */
          a = subnum(a, b_in);
          /* c = c + 1 */
          c = addnum(c, plus_one);
        }
      }
    }
    return c;
  }
 
  long BTtodecimal(BTnumber a)
  /* convert Balanced Ternary to decimal */
  {
    long result;
    long b;
    int i;
 
    b = 1;
    result = 0;
    for (i=0; i < (a.length); i++) {
      result = result + b * a.digit[i];
      b = b * 3;
    }
    return result;
  }
 
  BTnumber decimaltoBT(long value) {
  /* convert decimal to Balanced Ternary */
    BTnumber result = new BTnumber();
    long target, val, goal;
    int pos;
 
    result.length = 0;
    target = value;
    pos = 0;
    val = 1;
    goal  = 2 * target;
    if (goal < 0) {
      goal = -goal;
    }
    while (val < goal) {
      val = 3 * val;
      pos = pos + 1;
    }
    if (pos >= result.MAXLEN-1) {
      error("Overflow error");
      pos = -1;
    }
    if ( target < 0) {
      val = -val;
    }
    while (pos >= 0) {
      if (Math.abs(target-val) < Math.abs(target)) {
        if (val > 0) {
          result.digit[pos] = 1;
          target = target - val;
        } else {
          result.digit[pos] = -1;
          target = target - val;
        }
        if (result.length == 0) {
          result.length = pos+1;
        }
      } else {
        result.digit[pos] = 0;
      }
      val = val / 3;
      pos = pos - 1;
      /* make target and val the same sign */
      if ((target * val) < 0) {
        val = -val;
      }
    }
    return result;
  }
 
  void mshift(BTnumber n)
  /* shift left one place (multiply by 3) */
  {
    int i;
 
    if (n.length == n.MAXLEN) {
      error("Overflow Error");
    } else {
      n.length = n.length + 1;
      for (i=n.length-1; i>0; i--) {
        n.digit[i] = n.digit[i-1];
      }
      n.digit[0] = 0;
    }
  }
 
  void dshift(BTnumber n)
  /* shift right one place (divide by 3) */
  {
    int i;
 
    if (n.length > 0) {
      n.length = n.length - 1;
      for (i=0; i<n.length; i++) {
        n.digit[i] = n.digit[i+1];
      }
    }
  }
 

  void add() {
    if (pre_binary_op()) {
      stack[place-1] = addnum(stack[place], stack[place-1]);
      post_binary_op();
    }
  }

  void sub() {
    if (pre_binary_op()) {
      stack[place-1] = subnum(stack[place], stack[place-1]);
      post_binary_op();
    }
  }

  void mul() {
    if (pre_binary_op()) {
      stack[place-1] = mulnum(stack[place], stack[place-1]);
      post_binary_op();
    }
  }

  void div() {
    if (pre_binary_op()) {
      stack[place-1] = divnum(stack[place], stack[place-1]);
      post_binary_op();
    }
  }

  void todecimal() {
    long t;

    t = BTtodecimal(stack[place]);
    decimalbox.setText(String.valueOf(t));
  }

  void fromdecimal() {
    long t;

    if (onresult) {
      onresult = false;
      if (place < 4) {
        place = place + 1;
      }
    }
    t = Integer.valueOf(decimalbox.getText()).longValue();
    stack[place] = decimaltoBT(t);
    decimalbox.setText("");
    refresh(place);
    onresult = true;
  }

  void neg() {
    stack[place].negate();
    refresh(place);
  }
}

class BTnumber {
  static int MAXLEN = 20;
  int digit[] = new int[MAXLEN];
  int length;

  BTnumber() {
    this.length = 0;
  }

  public void takevalue(BTnumber n) {
    int j;

    this.length = n.length;
    for (j=0; j<length; j++) {
      this.digit[j] = n.digit[j];
    }
  }

  public void AddDigit(int d) {
    int j;

    if ((length > 0) || (d != 0)) {
      if (length < MAXLEN) {
        for (j=this.length; j>0; j--) {
          this.digit[j] = this.digit[j-1];
        }
        this.digit[0] = d;
        this.length = this.length + 1;
      }
    }
  }

  public void zero() {
    this.length = 0;
  }

  public String textify() {
    int j;
    StringBuffer out;
    String map = "-01";
    out = new StringBuffer(MAXLEN);

    if (this.length <= 0) {
      out.append("0");
    } else {
      for (j=this.length-1; j>=0; j--) {
        out.append(map.charAt(this.digit[j]+1));
      }
    }
    return out.toString();
  }

  void negate() {
  /* a = -a */
    int i;
 
    for (i=0; i < length; i++) {
      digit[i] = -digit[i];
    }
  }

}



13 Aug 2008 00:52
Profile
Retired

Joined: 03 Aug 2003 22:37
Posts: 1474
Location: Moscow
Reply with quote
And the html-source to run calculator applet:

Code:
<HTML>
<HEAD>
<BASE HREF="http://perun.hscs.wmin.ac.uk/~jra/ternary/calculator/">

<TITLE>Balanced Ternary Calculator</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF">
<h1>Balanced Ternary Calculator</h1>
Below is a simple stack-based balanced ternary calculator written in Java.
<APPLET CODE="Calculator.class" WIDTH=400 HEIGHT=200>
</APPLET>
<P>
The buttons are :
<UL>
<LI><b>-1</b>, <b>0</b> and <b>+1</b> to enter a number.

<LI><b>AC</b> clear entry and start again.
<LI><b>PUSH</b> entry finished - ready to enter next number.
<LI><b>POP</b> remove top item from stack.
<LI><b>+</b>, <b>-</b>, <b>x</b> and <b>/</b> perform the appropriate action
on the top 2 items on the stack.

<LI><b>DEC</b> display decimal value of current number in the bottom slot.
<LI><b>NEG</b> negate current entry.
</UL>
Enter a decimal number in the
bottom slot and it will be converted to balanced ternary and placed on the
stack.
<p>
Here is the <A HREF="Calculator.java">Java source</A>.
<HR>
Written by <A HREF="http://diana.ecs.soton.ac.uk/~jra/cv.html">James
Allwright</A>.
</BODY>

<SCRIPT language="Javascript">
<!--

// FILE ARCHIVED ON 20040906154742 AND RETRIEVED FROM THE
// INTERNET ARCHIVE ON 20080813074243.
// JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
// ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
// SECTION 108(a)(3)).

   var sWayBackCGI = "http://web.archive.org/web/20040906154742/";

   function xResolveUrl(url) {
      var image = new Image();
      image.src = url;
      return image.src;
   }
   function xLateUrl(aCollection, sProp) {
      var i = 0;
      for(i = 0; i < aCollection.length; i++) {
         if (typeof(aCollection[i][sProp]) == "string") {
          if (aCollection[i][sProp].indexOf("mailto:") == -1 &&
             aCollection[i][sProp].indexOf("javascript:") == -1) {
            if(aCollection[i][sProp].indexOf("http") == 0) {
                aCollection[i][sProp] = sWayBackCGI + aCollection[i][sProp];
            } else {
                aCollection[i][sProp] = sWayBackCGI + xResolveUrl(aCollection[i][sProp]);
            }
         }
         }
      }
   }

   xLateUrl(document.getElementsByTagName("IMG"),"src");
   xLateUrl(document.getElementsByTagName("A"),"href");
   xLateUrl(document.getElementsByTagName("AREA"),"href");
   xLateUrl(document.getElementsByTagName("OBJECT"),"codebase");
   xLateUrl(document.getElementsByTagName("OBJECT"),"data");
   xLateUrl(document.getElementsByTagName("APPLET"),"codebase");
   xLateUrl(document.getElementsByTagName("APPLET"),"archive");
   xLateUrl(document.getElementsByTagName("EMBED"),"src");
   xLateUrl(document.getElementsByTagName("BODY"),"background");
   var forms = document.getElementsByTagName("FORM");
   if (forms) {
       var j = 0;
       for (j = 0; j < forms.length; j++) {
              f = forms[j];
              if (typeof(f.action)  == "string") {
                 if(typeof(f.method)  == "string") {
                     if(typeof(f.method) != "post") {
                        f.action = sWayBackCGI + f.action;
                     }
                  }
              }
        }
    }


//-->
</SCRIPT>

</HTML>




13 Aug 2008 00:54
Profile
Reply with quote
Thanks, for the code,
actually i was looking for the code for devision, and its there....:-)


14 Aug 2008 05:57
Retired

Joined: 03 Aug 2003 22:37
Posts: 1474
Location: Moscow
Reply with quote
Yes, it seems to be the only public code that does division with balanced ternary numbers.


14 Aug 2008 06:10
Profile
Maniac

Joined: 17 Sep 2012 13:36
Posts: 277
Location: 81.170.128.52
Reply with quote
Do you know what license it's released under?


14 Aug 2008 10:09
Profile
Retired

Joined: 03 Aug 2003 22:37
Posts: 1474
Location: Moscow
Reply with quote
I've got no idea about license, he just uploaded the code to his own web-site, nothing more.


14 Aug 2008 13:14
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
eudoxie wrote:
Do you know what license it's released under?


There is no copyright notice, just "Developed by James Allwright" message, so it looks like "public domain"...

See some historical snapshot of that web-page from 2005:

http://web.archive.org/web/200502110914 ... a/ternary/

E-mail of author is J.R.Allwright@westminster.ac.uk


14 Aug 2008 22:31
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
up

_________________
:dj: https://mastodon.social/@Shaos


10 Nov 2012 07:01
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 9 posts ] 

Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.