binarybit-manipulationcomputer-scienceminecraftones-complement

How to turn a 16-bit number in one's complement into it's 7-segment display equivalence?


I have a 16-bit integer, in one's complement, and I'm trying to retrieve it's 7-seg display equivalence. Using only bitwise operations.

I'm doing it for a Minecraft project/hobby, just trying to build a full adder with negative operands.

I want the resulting integer to be transformed from a 16 bit integer, to a 5 digit 7-segment display, like this: A 16-bit binary integer with a 5 digit 7-segment display above

I understand logic gates but am a beginner in computer logic, so if you can explain me in the simplest terms or maybe programatically, like using Java or Python, it'd be better.

Actually, I don't know a bit of how to do it, I tried to search for answers and ask AI, but didn't got any plausible answer. I need something that uses only bitwise operations, and to be explained using them, if possible. I'm a begginer in computer theory. If you can explain me step-by-step and/or using simple terms, I'd be grateful.


Solution

  • In a comment, the O/P said "... Better yet, if you can only explain how binary to BCD conversion work, it'd already be sufficient."

    So, this answer will be mostly about converting to BCD. Converting a number to a seven segment display limited to bitwise operations is more than I care to get into.

    BCD (Binary Coded Decimal) is simply any representation of a number such that, when the number is expressed in base ten, each digit is represented in binary.

    Suppose I have 27 (decimal). In binary, that is 11011. If it is coded in BCD, the bits would look like this: 0010 0111. Note that 0010 is 2 in decimal, representing the first digit, and 0111 is 7 in decimal, representing the second digit.

    BCD uses 4 bits, or one nybble, for each digit. The storage units used are up to the developer. The developer could choose to have 1 byte, short, or int for each digit. Or, two digits might be stored in each byte. Or, 4 digits might be stored in each short. Or, 8 digits might be stored in each int.

    Here is a method that converts an integer to BCD with 8 digits in an int return type. There is no provision allowing for a sign:

    public static int bcd8Pack (int n) {
       int packed = 0;
       for (int i = 0; i < 8; ++i) {
          int digit = n % 10;
          n /= 10;
          int place = digit << (i * 4);
          packed = packed | place;
       }
       return packed;
    }
    

    Example use:

    System.out.println (Integer.toUnsignedString (bcd8Pack (98_765_432),16));`
    

    Output: 98765432

    Let us suppose we have a class with an instance field private final byte [] bcd; . It might convert an int to BCD with one digit per byte:

    public void set (int n) {
       int m = Math.abs (n);
       for (int i = bcd.length - 1 ; i >= 1 ; --i ) {
          bcd [i] = (byte) (m % 10);
          m /= 10;
       }
       bcd [0] = (byte) ( n < 0 ? MINUS_FLAG : PLUS_FLAG );        
    }
    

    This assumes element [0] has been reserved for a sign, which may have one of two values (MINUS_FLAG or PLUS_FLAG).

    For converting a decimal digit to a 7 segment display, we want to convert the digit into a binary number such that each bit corresponds to one segment. The bit to segment matching can be arbitrary. A "map" is in the code below. For the conversion, instead of using bitwise operations, I would use a translation table.

    The code below includes a simulation of a 7-segment display using a low resolution 7 x 5 dot-matrix format. The code uses a 7 x 7 dot-matrix because I reserved the left and right columns for spacing. The dot matrix output is there only to test the translation table approach.

    public class DigitalDisplay {
        
        /*  Seven segment map:
         *       -5-
         *      |   |
         *      4   0
         *      |   |
         *       -6- 
         *      |   |
         *      3   1
         *      |   |
         *       -2- 
        */
        
        /*  0123456
              ***   0
             *   *  1
             *   *  2
              ***   3
             *   *  4
             *   *  5
              ***   6
        */
        
        private static final byte MINUS_FLAG = 0xd; 
        private static final byte PLUS_FLAG = 0xc; 
        public  static final char SPACE = ' ';
        public  static final char ON = '*';
        
        private final byte [] bcd;
        
        static class Digit {
            
            private static final byte [] translate = {
                  0b00111111, 0b00000011, 0b01101101, 0b01100111, 0b01010011 
                , 0b01110110, 0b01111110, 0b00110011, 0b01111111, 0b01110111  };
            private static final byte MINUS_SIGN =  0b01000000;
            private static final byte PLUS_SIGN = 0;
     
            char [][] display;
            
            Digit () {
                setEmpty ();            
            }
            
            /* value is from 0 to 9 or 12 or 13. 
                      12 represents a plus sign. 13 represents a minus sign 
            */
            Digit (byte value) {  
                setEmpty ();  
                byte register; 
                switch (value)  {
                    case MINUS_FLAG:
                        register = MINUS_SIGN;
                        break;
                    case PLUS_FLAG:
                        register = PLUS_SIGN;
                        break;
                    default:
                        register = translate [value];
                        break;                                
                } // end switch (value)
                if ((register & 0b1) == 1) {   // segment 0
                    display [1][5] = ON;
                    display [2][5] = ON;
                }
                if ((register & 0b10) == 2) {  // segment 1
                    display [4][5] = ON;
                    display [5][5] = ON;                
                }
                if ((register & 0b100) == 4) {  // segment 2
                    display [6][2] = ON;
                    display [6][3] = ON;
                    display [6][4] = ON;
                }
                if ((register & 0b1000) == 8) { // segment 3
                    display [4][1] = ON;
                    display [5][1] = ON;                
                }
                if ((register & 0b1_0000) == 16 ) { // segment 4
                    display [1][1] = ON;
                    display [2][1] = ON;
                }
                if ((register & 0b10_0000) == 32) { // segment 5
                    display [0][2] = ON;
                    display [0][3] = ON;
                    display [0][4] = ON;
                }
                if ((register & 0b100_0000) == 64) { // segment 6
                    display [3][2] = ON;
                    display [3][3] = ON;
                    display [3][4] = ON;
                }
            }
            private void setEmpty () {
                display = new char [7][7];
                for (int i = 0; i < display.length; ++i) {
                    Arrays.fill (display [i], SPACE);
                }
            }
        } // end class Digit 
        
        
        
        public DigitalDisplay () {
            bcd = new byte [6]; // default size = 5 digits and 1 sign
        }
        
        public DigitalDisplay (int numDigits) {
            bcd = new byte [numDigits + 1]; // alow an extra for the sign
        }
        
        public void set (int n) {
            int m = Math.abs (n);
            for (int i = bcd.length - 1 ; i >= 1 ; --i ) {
                bcd [i] = (byte) (m % 10);
                m /= 10;
            }
            bcd [0] = (byte) ( n < 0 ? MINUS_FLAG : PLUS_FLAG );        
        }
           
        public String[] display () {
            Digit [] displayDigit = new Digit [bcd.length];
            for (int i = 0; i <  displayDigit.length; ++i) {
                displayDigit [i] = new Digit (bcd[i]);
            }
            
            String [] theDisplay = new String [displayDigit[1].display.length];
            StringBuilder [] displayNumber =
                    new StringBuilder [displayDigit[1].display.length]; 
            for (int lineIndex = 0; lineIndex < displayNumber.length; ++lineIndex) {
                displayNumber [lineIndex]  = new StringBuilder 
                             (bcd.length * displayDigit[1].display[0].length);
                for (int  digitIndex = 0
                        ; digitIndex < displayDigit.length
                        ; ++digitIndex) {
                    for (int digitColumnIndex = 0; 
                        digitColumnIndex < displayDigit[digitIndex].display.length; 
                        ++digitColumnIndex) {
                        displayNumber[lineIndex]
                           .append (displayDigit[digitIndex]
                                   .display[lineIndex][digitColumnIndex]);     
                    }
                }
                theDisplay [lineIndex] = displayNumber[lineIndex].toString();
            }
                   
            return theDisplay;         
        }
        
        public static void print (DigitalDisplay disp) {
            String [] out = disp.display ();
            for (int i = 0; i < out.length; ++i) {
                System.out.println (out[i]);
            } 
            System.out.println ("\n\n");
        }
    
        public static void main(String[] args) {        
            DigitalDisplay tenDigits = new DigitalDisplay (10);
            tenDigits.set (-1234567890);
            print (tenDigits);
            DigitalDisplay fiveDigits = new DigitalDisplay (5);
            fiveDigits.set (1234567);
            print (fiveDigits);
        }    
    }
    
    

    Output:

    :
    98765432
                    ***    ***           ***    ***    ***    ***    ***    ***  
                *      *      *  *   *  *      *      *   *  *   *  *   *  *   * 
                *      *      *  *   *  *      *      *   *  *   *  *   *  *   * 
      ***           ***    ***    ***    ***    ***           ***    ***         
                *  *          *      *      *  *   *      *  *   *      *  *   * 
                *  *          *      *      *  *   *      *  *   *      *  *   * 
                    ***    ***           ***    ***           ***    ***    ***  
    
    
    
             ***           ***    ***    ***  
                *  *   *  *      *      *   * 
                *  *   *  *      *      *   * 
             ***    ***    ***    ***         
                *      *      *  *   *      * 
                *      *      *  *   *      * 
             ***           ***    ***         
    

    If there were a real 7-segment display, the value of register would be passed to an area tied to the display. The if ((register & ... statements are present only to set the values in the dot-matrix simulation.

    Perhaps someone can edit this answer to replace the dot-matrix simulation with Swing or other graphics.

    Note that this answer does not address one's-complement and two's complement.