我正在Java和iPhone/OBJC客户端发送数据。 Java客户端具有已建立的中间件组件,我用来测试将新客户端集成到中间件的集成。

我对所有字节移动操作都有问题。 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);
}

当我发送[[[wvdouble alloc] initwithDouble:-13456.134]时

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

//--------------------------------------------------------------------------------

`

有帮助吗?

解决方案

正如@Vovanium所指出的那样,您将获得双重的长长值,示例将返回-13456。没有分数,没有指数。

在您的轮班和面具操作中,您要施放到INT过早。您需要在换档后应用演员表。另外,将其包装在循环中可以减少代码安装的更改。

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双倍, ,Java预计这些位将有一个特定的订单。如果从double到未签名的长长铸造不会产生该位顺序,则将获得不正确的值。在这种情况下,可能有必要在发送之前重新排列钻头。

位63(Mask 0x8000000000000000L选择的位)表示浮点数的符号。位62-52(Mask 0x7ff0000000000000l选择的位)代表指数。位51-0(由蒙版0x000fffffffffffl选择的位)代表浮点数的显着(有时称为Mantissa)。

更新:

确保您选择 @Vovanium的更改,以便您正在处理正确的一组:

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;

这只是扭转了长期解码的顺序。

其他提示

OBJC代码传输了长整数的位模式(通过Unsignedlonglongvalue获得),Java代码试图将其解释为双重模式。当访问ull时,您会使用双重价值获得双重模式。

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

如果您以sizeof(n)(8个字)或sizeof(i)(4 bytes)的方式发送数据,您应该期望一次读取8或4个字节。我怀疑您打算一次发送一个字节,因此数据类型应该是字节,长度应为1。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top