Java 将协议格式从浮点解码为字节

Java 将协议格式从浮点解码为字节,java,Java,我有密码: public float encode(byte val) { val = (byte) (val >> 3); val = (byte) (val & 0x1F); return (float) (val + 10) / 10.0f; } 我想反转它,我知道第一(LSB)位是100,我尝试了下面的代码,它不会工作,请帮助 public byte decode(float val) { val *= 10.0

我有密码:

public float encode(byte val) {
    val = (byte) (val >> 3);
    val = (byte) (val & 0x1F);
    return (float) (val + 10) / 10.0f;
}
我想反转它,我知道第一(LSB)位是100,我尝试了下面的代码,它不会工作,请帮助

   public byte decode(float val) {
            val *= 10.0f;
            val -= 10;
            int tmp = (int)val;
            byte tmp2 = (byte) (tmp << 3);
            tmp2= (byte) (tmp2 | 4);
            return tmp2;
            //4=100
}
从1.0到4.1,我得到正确的值,在4.1错误的值之后

4.1, 4.1
4.2, 1.0
4.3, 1.1
4.4, 1.2
4.5, 1.3
4.6, 1.4

由于乘法后会出现整数,请尝试对数字进行四舍五入:

public static byte decode(float val) {
    val = Math.round(val * 10.0f);
    val -= 10;
    ...
}

由于精度不高,乘法结果可能刚好低于整数(如
31.9999999 f
而不是
32.0f
)。

如您预期乘法后的整数,请尝试将数字四舍五入:

public static byte decode(float val) {
    val = Math.round(val * 10.0f);
    val -= 10;
    ...
}
由于精度不高,乘法结果可能刚好低于整数(如
31.99999f
而不是
32.0f
)。

尝试以下方法:

float byteToFloat (byte byteVal) {
    final byte[] bytes = { 0, 0, 0, byteVal }
    return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();
}

byte floatToByte (float floatVal) {
   final int bits = Float.floatToIntBits(floatVal);
   return (byte)(bits & 0xff);
}
试试这个:

float byteToFloat (byte byteVal) {
    final byte[] bytes = { 0, 0, 0, byteVal }
    return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();
}

byte floatToByte (float floatVal) {
   final int bits = Float.floatToIntBits(floatVal);
   return (byte)(bits & 0xff);
}

首先,
decode
表示将协议级数据转换为应用程序级,而
encode
表示将应用程序数据转换为传输级(例如)。你给相反的方法命名。其次,对于超过256个字节的值,这种方法没有意义,因为字节只有256个不同的值(您不使用3位,所以您只能传输2^5=32个不同的浮点值)。第三,您的测试应该检查传入的应用程序数据是否通过传输协议并恢复到初始状态。请看我的代码:

public static float decode(byte val) {
    val = (byte) (val >> 3);
    val = (byte) (val & 0x1F);
    return (float) (val + 10) / 10.0f;
}
public static byte encode(float val) {
    val *= 10.0f;
    val -= 10;
    int tmp = (int)val;
    byte tmp2 = (byte) (tmp << 3);
    return tmp2;
}

public static void main(String[] args) {
    for (int i = Byte.MIN_VALUE; i < Byte.MAX_VALUE; i++) {
        float f =  decode((byte)i);
        System.out.printf("%s\t%s%n", f, decode(encode(f)));
    }
}
公共静态浮点解码(字节val){
val=(字节)(val>>3);
val=(字节)(val&0x1F);
返回(浮动)(val+10)/10.0f;
}
公共静态字节编码(浮点值){
val*=10.0f;
val-=10;
int tmp=(int)val;

字节tmp2=(byte)(tmp首先
decode
表示将协议级数据转换为应用程序级,而
encode
表示将应用程序数据转换为传输级(例如)。方法的名称正好相反。其次,对于超过256个字节的值,此方法没有意义,因为字节只有256个不同的值(您不使用3位,因此只能传输2^5=32个不同的浮点值)。第三,您的测试应检查传入的应用程序数据是否通过传输协议并恢复到初始状态。请查看我的代码:

public static float decode(byte val) {
    val = (byte) (val >> 3);
    val = (byte) (val & 0x1F);
    return (float) (val + 10) / 10.0f;
}
public static byte encode(float val) {
    val *= 10.0f;
    val -= 10;
    int tmp = (int)val;
    byte tmp2 = (byte) (tmp << 3);
    return tmp2;
}

public static void main(String[] args) {
    for (int i = Byte.MIN_VALUE; i < Byte.MAX_VALUE; i++) {
        float f =  decode((byte)i);
        System.out.printf("%s\t%s%n", f, decode(encode(f)));
    }
}
公共静态浮点解码(字节val){
val=(字节)(val>>3);
val=(字节)(val&0x1F);
返回(浮动)(val+10)/10.0f;
}
公共静态字节编码(浮点值){
val*=10.0f;
val-=10;
int tmp=(int)val;

字节tmp2=(字节)(tmp)你确定第一个
编码是正确的,你只有7位加上一个符号,但你丢弃了低3位,这意味着你只有4位。丢弃的3位应该设置为什么?我测试了
解码(编码(字节))
对于所有可能的100 LSB字节,它工作得非常好。您是否使用
float
值进行任何额外的转换?可能是序列化/反序列化?在它不工作时向我们显示完整的代码。这可能是舍入错误。@Peter Lawrey。我编写了第二种方法
decode
,第一种方法
encode
是某个程序的代码。
解码的结果是wrong@TagirValeev,我加了一句code@J.Davied,什么是协议编码(浮点)
在您的测试代码中?您提供了唯一接受字节的
encode
方法。您确定第一个
encode
是正确的,您只有7位加上一个符号,但您正在丢弃较低的3位,这意味着您只有4位。丢弃的3位应该设置为什么?我测试了
解码(encode(byte))
对于所有可能的100 LSB字节,它工作得非常好。您是否使用
float
值进行任何额外的转换?可能是序列化/反序列化?在它不工作时向我们显示完整的代码。这可能是舍入错误。@Peter Lawrey。我编写了第二种方法
decode
,第一种方法
encode
是某个程序的代码。
解码的结果是wrong@TagirValeev,我加了一句code@J.Davied,什么是测试代码中的
protocol.encode(float)
?您提供了唯一接受字节的
encode
方法。