0

I have the class Element, which has the following attributes (see class). Since the range of the two integer values are very small, I want to store them in a short. This does not work for me. I want to work with the bitshifting. What am I doing wrong here? It is a school assignment, so it must be a short.


public class Element implements Externalizable {
    private static final long serialVersionUID = 6529685098267757690L;
    private boolean isMarked;
    private    boolean isValid;
   private boolean isDeleted;
    private int key; // VALUE AREA: 0-500
    private int value; // VALUE AREA: 1-10
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        short val =0;
        if(this.isMarked) val|=1;
        val <<=1;
        if(this.isValid) val|=1;
        val <<=1;
        if(this.isDeleted) val|=1;
        val <<=4;
        val |=  this.value;
        val <<=9;
        val |= (short) this.key;
        out.writeShort(val);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        short s = in.readShort();

        this.isMarked = s % 2==1;
        s >>= 1;
        this.isValid =s % 2==1;
        s >>>= 1;
        this.isDeleted = s % 2==1;
        s >>>= 4;
        this.value = s % 8;
        s >>>=9;
        this.value = s % 512;
    }

    @Override
    public String toString() {
        return "Element{" +
                "isMarked=" + isMarked +
                ", isValid=" + isValid +
                ", isDeleted=" + isDeleted +
                ", key=" + key +
                ", value=" + value +
                '}';
    }

    public Element(boolean isMarked, boolean isValid, boolean isDeleted, int key, int value) {
        this.isMarked = isMarked;
        this.isValid = isValid;
        this.isDeleted = isDeleted;
        this.key = key;
        this.value = value;
    }
    public Element(){}
}

Stift
  • 1
  • 1
  • *"This does not work for me."* ... what do you mean? Are you getting an exception? Is it not producing the output you expect? Why are you using the serialization mechanism? If you need serialization, why not use a serialization proxy? – scottb Jun 29 '21 at 20:16
  • You have to read the data in reverse order. (key, value, isDeleted, isValid, isMarked) You also have a typo, `this.value = s % 512` should be `this.key = s % 512`! –  Jun 29 '21 at 20:17
  • When I create the object like this: Element e = new Element(true,false,true,450,6); I get the value -62 for the attribute key when I read it out. There must be another error in my code. – Stift Jun 29 '21 at 20:24

1 Answers1

1

Read the data in reverse order. Use the binary and operator instead of the modulo operator, since short is signed. Negative numbers then lead to the problem described in your comment.

Change readExternal to:

@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    short s = in.readShort();

    this.key = s & 511; // masks the lower 9 bits
    s >>>= 9;
    this.value = s & 15; // masks the lower 4 bits
    s >>>= 4;
    this.isDeleted = (s & 1) == 1; 
    s >>>= 1;
    this.isValid = (s & 1) == 1;
    s >>>= 1;
    this.isMarked = (s & 1) == 1;
}
  • Why do I have to use 511 and not 512? – Stift Jun 30 '21 at 15:51
  • 511 (binary 0b111111111) masks (preserves) the bits 0 - 8 from your variable `s` all other bits are set to 0! The result is then between 0 and 511. 512 (binary 0b100000000) on the other hand masks (preserves) only bit 9 from `s` and sets all other bits to 0! The result is then 512 or 0. –  Jul 02 '21 at 09:14