Lossy conversion from int to byte?

is my simple encryption algorithm that I am doing as an exercise gives me a possible lossy conversion from int to byte? but i dont know why it is giving me this error any ideas?

public class Rot13Crypt extends CryptStream
{
    public Rot13Crypt(StreamPair theStreams)
    {
        super(theStreams);
    }
    protected byte [] cryptData(byte [] data, int len)
    {
        byte [] cryptedByte = new byte[len];
        for(int i = 0; i < len; i++)
        {
            cryptedByte[i] = (data[i] + 13) % 256;
        }
        return cryptedByte;
    }
    protected byte [] decryptData(byte [] data, int len)
    {
        byte [] decryptedByte = new byte[len];
        for(int i = 0; i < len; i++)
        {
            decryptedByte[i] = (data[i] * 256) - 13;
        }
        return decryptedByte;
    }
}

      

+2


source to share


7 replies


It throws this error message because you are trying to assign a sign value with an internal value byte

. This is a potentially decreasing operation: intuitively, you cannot put all possible values int

into byte

.

The Java language requires you to use translation (byte)

when you assign an int-value to an expression byte

.

There are two places where you do this:

   cryptedByte[i] = (data[i] + 13) % 256;

   decryptedByte[i] = (data[i] * 256) - 13;

      

In the first case, the value of the expression is in the range 0 to 255 ... but the Java values byte

are in the range -128 to +127.

In the second case, the values ​​of the expression can range from (-128 * 256) - 13

to `(+127 * 256) - 13. This is clearly not appropriate.

But this is actually a moot point. Java does not allow variations of the above code, even if you (a smart person) can prove that the range of the expression will "match" in byte

. The JLS prohibits this. (The Java compiler doesn't have to be a general theorem proof !!)

The only situation where an int-valued expression can be assigned byte

without using the cast type is when the expression is a compile-time constant expression and the actual value of the expression is in the range byte

.



If you are interested, it is stated in JLS 15.2 Assignment Contexts , which says:

Also, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion can be used if the type of the variable is byte, short, or char, and the value of the constant expression is represented in the type of the variable.

(You have to chase what the spec means "constant expression" and "narrowing primitive transformation". I'll leave that for interested people to do for myself.)


then I would add (byte) casting before 13 and 256?

Nope. You need to pass the entire expression; eg.

   cryptedByte[i] = (byte) ((data[i] + 13) % 256);

      

+4


source


In Java, a type int

is encoded using 32 bits and a type byte

using 8 bits. If you convert int

to byte

, you may lose information if your original value is greater than 127 or less than -128.



Integer literal has a default value int

and operations with int

return int

. So the result data[i] + 13

is int

; the same for (data[i] + 13) % 256

. When you try to store this result in byte

(cryptedByte [i] here) Java warns you about a "possible lossy conversion".

+3


source


A byte has 2 ^ 8 = 256 unique states, so the largest range it can represent is -128 to 127.

assuming that in

 decryptedByte[i] = (data[i] * 256) - 13;

      

A value data[i]

greater than 1

will result in exceeding the maximum byte value

+1


source


You have problems here.

cryptedByte[i] = (data[i] + 13) % 256;

      

and here

decryptedByte[i] = (data[i] * 256) - 13;

      

256

and 13

are type literals int

. When you perform operations on them and on a type that takes up less memory (in this example byte

), the type is promoted: data[i]

implicitly converted (promoted) to the type int

. Thus, both of these expressions are evaluated before int

. And you know what happens when you convert an int to a byte, right? You may lose data. This is because it is byte

limited to less memory than int

.

0


source


You just need to cast when assigning each byte when it is inside a variable, so java can make sure everything is between -127 and 127, which is the ascii range. The following should work:

public class Rot13Crypt extends CryptStream
{
    public Rot13Crypt(StreamPair theStreams)
    {
        super(theStreams);
    }
    protected byte [] cryptData(byte [] data, int len)
    {
        byte [] cryptedByte = new byte[len];
        for(int i = 0; i < len; i++)
        {
            cryptedByte[i] = (byte) (data[i] + 13) % 256;
        }
        return cryptedByte;
    }
    protected byte [] decryptData(byte [] data, int len)
    {
        byte [] decryptedByte = new byte[len];
        for(int i = 0; i < len; i++)
        {
            decryptedByte[i] = (byte) (data[i] * 256) - 13;
        }
        return decryptedByte;
    }

      

}

0


source


A byte is 8 bits in size and 32 bits in size. Thus, some information may be lost when performing this conversion!

-1


source


the data type of a byte is an 8-bit two-digit integer. int is a 32-bit signed two's complement integer.

Cannot fit integer into byte. Hence, a loss of precision. Hope this is clear.

Sample link here

-1


source







All Articles