代码之家  ›  专栏  ›  技术社区  ›  Jim Geldermann

帮助实现目标c-java字节移位

  •  0
  • Jim Geldermann  · 技术社区  · 15 年前

    所有字节移位操作都有问题。Java代码正在生产中,无法修改。既然这双似乎是最广泛的我会张贴它。

    从objC发送:

    -(void)putDouble:(NSNumber *)v{
    
        unsigned long long n = [v unsignedLongLongValue];
    
        dataToSend = [NSMutableData data];
    
        long long i = (int)n & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(n)]];
    
    
        i = ((int)n >> 8) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(n)]];
    
    
        i = ((int)n >> 16) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(n)]];
    
    
        i = ((int)n >> 24) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(n)]];
    
    
        i = ((int)n >> 32) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(i)]];
    
    
        i = ((int)n >> 40) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(i)]];
    
    
        i = ((int)n >> 48) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(i)]];
    
    
        i = ((int)n >> 56) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(i)]];
        [self send:dataToSend];
    
    }
    

    Java接收:

    /*
     * Retrieve a double (64-bit) number from the stream.
     */
    private double getDouble() throws IOException
    {
        byte[] buffer = getBytes(8);
    
        long bits =
                ((long)buffer[0] & 0x0ff) |
                (((long)buffer[1] & 0x0ff) << 8) |
                (((long)buffer[2] & 0x0ff) << 16) |
                (((long)buffer[3] & 0x0ff) << 24) |
                (((long)buffer[4] & 0x0ff) << 32) |
                (((long)buffer[5] & 0x0ff) << 40) |
                (((long)buffer[6] & 0x0ff) << 48) |
                (((long)buffer[7] & 0x0ff) << 56);
    
        return Double.longBitsToDouble(bits);
    }
    

    java获得双5.53E-322

    问题出在objC方面,因为java正在与其他开发环境一起生产。对于所有生产客户机-13456.134是转换后的结果。

    以下是java客户机使用的sendDouble代码:`

     // Write a double (64-bit) number to the stream.
    
    private void putDouble(double number) throws IOException
    {
        long n = Double.doubleToLongBits(number);
    
        // have to write these in reverse order to be comptible
    
        stream.write((int)(n) & 0x0ff);
        stream.write((int)((n >>> 8)) & 0x0ff);
        stream.write((int)((n >>> 16)) & 0x0ff);
        stream.write((int)((n >>> 24)) & 0x0ff);
        stream.write((int)((n >>> 32)) & 0x0ff);
        stream.write((int)((n >>> 40)) & 0x0ff);
        stream.write((int)((n >>> 48)) & 0x0ff);
        stream.write((int)((n >>> 56)) & 0x0ff);
    }
    
    //--------------------------------------------------------------------------------
    

    `

    3 回复  |  直到 15 年前
        1
  •  3
  •   Devon_C_Miller    15 年前

    正如@Vovanium所指出的,您得到的是double的long long值,对于您的例子,它将返回-13456。没有分数,没有指数。

    int i;
    int j;
    
    for (j = 0; j < sizeof(n); j++) {
        i = (int)(n >> (j*8)) & 0x0ff;
        [dataToSend appendData:[NSMutableData dataWithBytes:&i length:sizeof(i)]];
    }
    [self send:dataToSend];
    

    请注意,根据 JavaDocs for Double ,Java希望位具有特定的顺序。如果从double转换为unsigned long long long不产生该位顺序,则会得到不正确的值。在这种情况下,可能需要在发送之前重新排列位。

    位63(掩码0x80000000000000L选择的位)表示浮点数的符号。位62-52(由掩码0x7ff0000000000000L选择的位)表示指数。位51-0(由掩码0x000fffffffffffl选择的位)表示浮点数的有效位(有时称为尾数)。

    更新:

    double nd = [v doubleValue];
    unsigned long long n = *(long long *)&nd;
    

    尝试使用值-1.0进行测试。a-1.0的IEEE 754位模式是:

    0xbff0000000000000
    

    当序列化时,字节将是

    00 00 00 00 00 00 f0 bf
    

    如果得到这些字节:

    bf f0 00 00 00 00 00 00
    

    将我的示例代码中的行更改为

        i = (int)(n >> ((sizeof(n) - j - 1)*8)) & 0x0ff;
    

    这正好颠倒了long long被解码的顺序。

        2
  •  2
  •   Vovanium    15 年前

    ObjC代码传输长整数的位模式(由unsignedLongLongValue得到),Java代码试图将其解释为double的位模式。当作为ULL访问doubleValue时,应该使用doubleValue获得double的位模式。

    double nd = [v doubleValue];
    unsigned long long n = *(long long *)&nd;
    
        3
  •  1
  •   Peter Lawrey    15 年前

    推荐文章