java 从 int 到 byte 的有损转换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28623477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:54:58  来源:igfitidea点击:

lossy conversion from int to byte?

javaencryption

提问by Hotfin

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

我作为练习所做的简单加密算法给了我一个可能的从 int 到 byte 的有损转换?但我不知道为什么它会给我这个错误任何想法?

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;
    }
}

回答by Stephen C

It is giving that error message because you are attempting to assign the value of an int-valued expression to a byte. That is a potentially lossy operation: intuitively, you cannot put all possible intvalues into a byte.

它给出了该错误消息,因为您试图将 int 值表达式的值分配给byte. 这是一个潜在的有损操作:直观上,您不能将所有可能的int值放入byte.

The Java language requires you to use a (byte)cast when you assign an int-valued expression to a byte.

Java 语言要求您(byte)在将 int 值表达式分配给byte.

There are two places where you are doing this:

有两个地方你在做这个:

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

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

In the first one, the value of the expression is in the range 0 to 255 ... but Java bytevalues are in the range -128 to +127.

在第一个中,表达式的值在 0 到 255 的范围内……但 Javabyte值在 -128 到 +127 的范围内。

In the second one, the expression values potentially have values in the range (-128 * 256) - 13to `(+127 * 256) - 13. That clearly won't fit.

在第二个中,表达式值可能具有范围(-128 * 256) - 13为 `(+127 * 256) - 13 的值。这显然不适合。

But that is actually moot. The Java does not allow variants of the above code even if you (a smart human being) can provethat the range of the expression would "fit" into a byte. The JLS forbids this. (A Java compiler not required to be a general theorem prover!!)

但这实际上是没有意义的。Java 不允许上述代码的变体,即使您(一个聪明人)可以证明表达式的范围“适合”到byte. JLS 禁止这样做。(Java 编译器不需要是一般定理证明者!!)

The onlysituation where an int-valued expression can be assigned to a bytewithout a type-cast is when the expression is a compile-time constant expression ANDthe actual value of the expression is in the range of byte.

其中一个int值表达式可以被分配到的情况byte没有型铸造是当表达式是一个编译时间常量表达式表达式的实际值是在的范围内byte

If you are interested, this is specified in JLS 15.2 Assignment Contextswhich states:

如果您有兴趣,这在JLS 15.2 分配上下文中指定:

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

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

此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(第 15.28 节):

  • 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以在变量的类型中表示,则可以使用缩小原语转换。

(You need to chase down what the spec means by "constant expression" and "narrowing primitive conversion". I'll leave that for interested people to do for themselves.)

(您需要了解规范中“常量表达式”和“缩小原始转换”的含义。我将把它留给感兴趣的人自己做。)



so would i add a (byte) cast in front of the 13 and 256?

那么我会在 13 和 256 前面添加一个(字节)转换吗?

Nope. You need to cast the entire expression; e.g.

不。您需要转换整个表达式;例如

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

回答by osechet

In Java, the inttype is coded using 32 bits and the bytetype using 8 bits. If you convert an intto a byte, you may lose information if your original value is greater than 127 or less than -128.

在 Java 中,int类型使用 32 位编码,byte类型使用 8 位编码。如果将 an 转换int为 a byte,如果原始值大于 127 或小于 -128,则可能会丢失信息。

An integer literal is by default an intand operations on intreturn int. So the result of data[i] + 13is an int; the same for (data[i] + 13) % 256. When you try to store that result into a byte(here cryptedByte[i]), Java warns you about the "possible lossy conversion".

默认情况下,整数文字是intintreturn的和操作int。所以结果data[i] + 13是一个int; 相同的(data[i] + 13) % 256。当您尝试将该结果存储到byte(此处为 cryptedByte[i])时,Java 会警告您“可能的有损转换”。

回答by Scary Wombat

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

一个字节有 2^8 = 256 个唯一状态,因此它可以表示的最大范围是 -128 到 127。

so assuming that in

所以假设在

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

the data[i]value is greater than 1will cause the value to overflow the max value of a byte

data[i]值大于1将导致该值溢出一个字节的最大值

回答by Mints97

You have problems here

你这里有问题

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

and here

和这里

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

256and 13are literals of type int. When you perform operations with them and with a type that occupies less memory (in this example, byte), type promotionoccurs: data[i]is implicitlyconverted (promoted) to type int. Thus, both these expressions evaluate to int. And you know what happens when you convert an int to a byte, right? You can losedata. That is because a byteis limited to less memory than int.

25613是类型的文字int。当你与他们和占用更少的内存(在这个例子中,一个类型进行操作byte),类型提升情况:data[i]隐式转换(晋升)输入int。因此,这两个表达式的计算结果都是int。您知道将 int 转换为字节时会发生什么,对吗?您可能会丢失数据。那是因为 a 的byte内存限制少于int

回答by Maf

You just need to do a cast when assigning each byte when it's inside a variable, so java can assure all are between -127 and 127 which is the ascii range. The folowing should work:

当分配每个字节在变量内时,您只需要进行强制转换,因此 java 可以确保所有字节都在 -127 和 127 之间,这是 ascii 范围。以下应该工作:

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;
    }

}

}

回答by Juce

Bytes have a size of 8 bits and ints a size of 32 bits. So some information may be lost by doing this conversion!

字节大小为 8 位,整数大小为 32 位。所以做这个转换可能会丢失一些信息!

回答by Gyan

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

byte 数据类型是一个 8 位有符号二进制补码整数。int 数据类型是一个 32 位有符号二进制补码整数。

Can't fit an integer into a byte. Hence, the loss in precision. I hope it's clear.

不能将整数放入一个字节中。因此,精度损失。我希望很清楚。

A sample reference is here

示例参考在这里