ObjC从流中获取64位数

时间:2010-11-09 16:09:15

标签: iphone objective-c stream byte

我成功将64位数字从objC客户端传递到java客户端,但无法发送到objC客户端。

Java代码         / *      *从流中检索双(64位)数字。      * /     private double getDouble()抛出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);
}

objC代码

/*
 * Retrieve a double (64-bit) number from the stream.
 */
- (double)getDouble
{
    NSRange dblRange = NSMakeRange(0, 8);
    char buffer[8];

    [stream getBytes:buffer length:8];
    [stream replaceBytesInRange:dblRange withBytes:NULL length:0];

    long long bits =
    ((long long)buffer[0] & 0x0ff) |
    (((long long)buffer[1] & 0x0ff) << 8) |
    (((long long)buffer[2] & 0x0ff) << 16) |
    (((long long)buffer[3] & 0x0ff) << 24) |
    (((long long)buffer[4] & 0x0ff) << 32) |
    (((long long)buffer[5] & 0x0ff) << 40) |
    (((long long)buffer[6] & 0x0ff) << 48) |
    (((long long)buffer[7] & 0x0ff) << 56);

    NSNumber *tempNum = [NSNumber numberWithLongLong:bits];
    NSLog(@"\n***********\nsizeof long long %d \n tempNum: %@\nbits %lld",sizeof(long long), tempNum, bits);
    return [tempNum doubleValue];
}

NSLog的结果是


sizeof long long 8  tempNum:-4616134021117358511 位-4616134021117358511

号码应为:-1.012345


问题是我试图在getDouble func中将Java转换为objC。我的中间件考虑了endian问题。简单的解决方案是目标是小端

- (double)getDouble

NSRange dblRange = NSMakeRange(0, 8);
double swapped;

[stream getBytes:&swapped length:8];
[stream replaceBytesInRange:dblRange withBytes:NULL length:0];



return swapped;

感谢大家的投入 - 从这次练习中获得了很多经验和一点理解。

2 个答案:

答案 0 :(得分:3)

双长长不是一回事。 long表示整数,其没有小数部分,double表示浮点数,其具有小数部分。这两种类型在内存中表示其值的方式完全不同。也就是说,如果你要查看代表数字4000的长整数位,并将它们与代表数字4000的双精度位进行比较,它们会有所不同。

正如Wevah所说,第一步是在调用NSLog()时使用正确的double类型和正确的%f格式化程序。

但是,我想补充一点,你还需要小心,以运行C代码的机器的本机顺序获取字节。有关我所指的内容的详细说明,请参阅http://en.wikipedia.org/wiki/Endianness简短版本是不同的处理器可能在内存中以不同的方式表示数字,并且您需要在代码中确保一旦获得一堆字节在您尝试将其解释为数字之前,您将从网络中为处理器按正确顺序放置字节。

幸运的是,这是一个已解决的问题,可以通过使用CoreFoundation中的CFConvertFloat64SwappedToHost()函数轻松解决:

[stream getBytes:buffer length:8];
[stream replaceBytesInRange:dblRange withBytes:NULL length:0];

double myDouble = CFConvertFloat64SwappedToHost(*((double*)buffer));
NSNumber *tempNum = [NSNumber numberWithDouble:myDouble];
NSLog(@"\n***********\nsizeof double %d \n tempNum: %@\nbits %f",sizeof(double), tempNum, myDouble);
return [tempNum doubleValue];

答案 1 :(得分:0)

您可能希望将其转换为double(可能/可能通过联合;请参阅Jonathan的评论)并使用%f说明符。