import java.applet.*; import java.awt.event.*; import java.awt.*; import java.math.*; /** * @author R. J. Mathar www.strw.leidenuniv.nl/~mathar * @since 2007-11-07 */ public class gray extends Applet implements ActionListener { static final String COMPUTE = " Compute!" ; /* Determines the direction of the conversion, * Gray to straight, the inverse of thsi operation or * keep the input (in case of which this is just a base conversion routine) */ Choice direc ; /* Base of the input, 2, 10, 16 etc up to 36 */ Choice base ; TextArea resulT ; Button comp ; Panel Direc ; Panel Base ; Panel Comp ; Panel Resul ; /* global labels */ Label Lbl1 = new Label("Input number:") ; Label Lbl2 = new Label("Input number basis:") ; Label Lbl3 = new Label("Output:") ; TextField inn ; // input number GridBagLayout gridbag ; GridBagConstraints gridconstr ; /** */ public void init() { Direc = new Panel() ; setLayout(new FlowLayout(FlowLayout.CENTER,7,1)) ; /* The three different actions that are supported. */ direc = new Choice(); direc.add("input Gray, output binary") ; direc.add("input binary, output Gray") ; direc.add("input = output") ; Direc.add(direc) ; Base = new Panel() ; Base.add(Lbl1) ; /* To show how it works, take a 33 as an example * for the input of the initial input field. */ inn = new TextField("33",32) ; Base.add(inn) ; Base.add(Lbl2) ; /* The input bases. Put the decimal system at the top, * the binary, hexadecimal etc to follow. */ base = new Choice() ; base.add("10") ; base.add("2") ; base.add("16") ; for(int i=3; i <= 36 ; i++) if ( i != 10 && i != 2 && i != 16) base.add(Integer.toString(i)) ; Base.add(base) ; Comp = new Panel() ; /* Install and Activate the "Compute" button */ comp= new Button(COMPUTE) ; comp.setEnabled(true) ; comp.setActionCommand(COMPUTE) ; comp.addActionListener(this) ; Comp.add(comp) ; Resul = new Panel() ; Resul.add(Lbl3) ; resulT = new TextArea("") ; resulT.setEditable(false) ; Resul.add(resulT) ; /* Put the two scroll bars and the * input and output area onto the screen */ add(Direc) ; add(Base) ; add(Comp) ; add(Resul) ; } /** Convert binary to Gray code. * @parameter n the original number * @return the Gray coded result */ public int btg(int n) { return n ^ (n >> 1) ; } /** Convert binary to Gray code. * The difference to the other coding above is that this here allows * larger numbers with the BigInteger support, where binary operations * are to be implemented by functions rather than the intrinsic language * operations. * @parameter n the original number * @return the Gray coded result */ public BigInteger btg(BigInteger n) { return n.xor(n.shiftRight(1)) ; } /** Convert Gray code to straight representations. * @parameter n Gray coded number * @result normal (straight) representation * @see midi/mii/src/miiGrayCode.c in the MIDI ESO CMM */ public int gtb(int n) { for(int i= (n >> 1) ; i != 0 ; n ^= i, i >>= 1) ; return n ; } /** Convert Gray code to straight representation. * The binary operations of the integer operands are re-coded in * the BigInteger functionality. * @parameter n Gray coded number * @result normal (straight) representation * @see midi/mii/src/miiGrayCode.c in the MIDI ESO CMM */ public BigInteger gtb(BigInteger n) { for(BigInteger i= n.shiftRight(1) ; i.compareTo(BigInteger.ZERO) != 0 ; n = n.xor(i), i=i.shiftRight(1) ) ; return n ; } /** Convert a positive decimal integer into a string * represenation in some basis. * @parameter n the non-negative integer * @parameter base the basis (like 10 for decimal, 2 for binary) for the * output representation. * @result the string representation. This uses letters A and later to * code the numbers 11 etc. */ public String toStr(int n, int base) { switch (base) { case 2: return Integer.toBinaryString(n) ; case 8: return Integer.toOctalString(n) ; case 16: return Integer.toHexString(n) ; default: return Integer.toString(n,base) ; } /* old and obsolete * int resid=n ; * String resul = "" ; * if( base <= 10 ) * do * { * resul = (resid % base)+ resul ; * resid /= base ; * } while (resid > 0 ) ; * } * else * { * do * { * final int frac = resid % base ; * if ( frac <= 9 ) * { * resul = frac + resul ; * } * else * { * switch (frac) * { * case 10: * resul = "a" + resul ; * break ; * case 11: * resul = "b" + resul ; * break ; * ... * case 25: * resul = "p" + resul ; * break ; * } * } * resid /= base ; * } while (resid > 0 ) ; * *return resul ; */ } /** Convert positive integer into a string representation * of some basis. This is the BigInteger analog of the function above. * @parameter n a non-negative positive integer * @parameter base a basis like 2 for binary, 10 for decimal. * @return the standard string representation, using letters A, B, C etc * to write down the digits of 11, 12 etc for bases which are larger than * 10. */ public String toStr(BigInteger n, int base) { return n.toString(base) ; } /** * @parameter e the information on which button had been pressed in the GUI */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand() ; if ( cmd == COMPUTE ) { /* old, integer-based version * int n = java.lang.Integer.parseInt(inn.getText(), new Integer(base.getSelectedItem()).intValue() ) ; * int resul ; * if ( direc.getSelectedItem().charAt(6) == 'G' ) // input Gray * resul=gtb(n) ; *else if ( direc.getSelectedItem().charAt(6) == 'b' ) // input binary * resul=btg(n) ; *else * resul= n ; */ /* maximum radix is 36 */ BigInteger n = new BigInteger(inn.getText(), new Integer(base.getSelectedItem()).intValue() ) ; /* The actions are simply decided on whether the * 6th character was a 'G' (meaning input was Gray coded), a 'b' * (meaning input was binary) or something else (meaning the input * will just be shown in different bases, but not recoded). */ BigInteger resul ; if ( direc.getSelectedItem().charAt(6) == 'G' ) /* input Gray */ resul=gtb(n) ; else if ( direc.getSelectedItem().charAt(6) == 'b' ) /* input binary = straight */ resul=btg(n) ; else resul= n ; /* the resulting number has been set above, and is shown in 4 standard * bases in the output field. */ resulT.setText(""+resul+"(decimal)") ; resulT.append("\n"+toStr(resul,2)+"(binary)") ; resulT.append("\n"+toStr(resul,8)+"(octal)") ; resulT.append("\n"+toStr(resul,16)+"(hex)") ; } } }