NSData的转换为基本变量与IEEE-754或二进制补码? [英] Convert NSData to primitive variable with ieee-754 or twos-complement?
问题描述
我在的OBJ-C 和可可新的程序员。我是一个试图写将用于读取二进制文件的框架(灵活的图像传输系统或 FITS 二进制文件,通常是由天文学家使用)。二进制数据,我感兴趣提取,可以有不同的格式和我通过阅读的头FITS 文件中获取其属性。
I am new programmer in Obj-C and cocoa. Im a trying to write a framework which will be used to read a binary files (Flexible Image Transport System or FITS binary files, usually used by astronomers). The binary data, that I am interested to extract, can have various formats and I get its properties by reading the header of the FITS file.
到现在为止,我设法创建一个类来存储在的内容符合文件和头隔离到一个的NSString
对象和二进制数据转换成的NSData code>对象。我也设法写方法,它让我从中提取标题是国米preT二进制数据非常有价值的核心价值观。
Up to now, I manage to create a class to store the content of the FITS file and to isolate the header into a NSString
object and the binary data into a NSData
object. I also manage to write method which allow me to extract the key values from the header that are very valuable to interpret the binary data.
现在我想在的NSData code>对象转换为基本类型数组
的(数组双
, INT
,短
...)。但是,在这里,我被卡住,并会AP preciate任何帮助。
I am now trying to convert the NSData
object into a primitive array (array of double
, int
, short
...). But, here, I get stuck and would appreciate any help.
据我对 FITS 文件,我有PT取决于价值的二进制数据5的可能性,除$ P $的 BITPIX $的文档C $ C>键:
According to the documentation I have about the FITS file, I have 5 possibilities to interpret the binary data depending on the value of the BITPIX
key:
BITPIX value | Data represented
8 | Char or unsigned binary int
16 | 16-bit two's complement binary integer
32 | 32-bit two's complement binary integer
64 | 64-bit two's complement binary integer
-32 | IEEE single precision floating-point
-64 | IEEE double precision floating-point
我已经写code的和平,表明波纹管,要尽量在的NSData code>转换为原始数组。
// self reefer to my FITS class which contain a NSString object
// with the content of the header and a NSData object with the binary data.
-(void*) GetArray
{
switch (BITPIX)
{
case 8:
return [self GetArrayOfUInt];
break;
case 16:
return [self GetArrayOfInt];
break;
case 32:
return [self GetArrayOfLongInt];
break;
case 64:
return [self GetArrayOfLongLong];
break;
case -32:
return [self GetArrayOfFloat];
break;
case -64:
return [self GetArrayOfDouble];
break;
default:
return NULL;
}
}
// then I show you the method to convert the NSData into a primitive array.
// I restrict my example to the case of 'double'. Code is similar for other methods
// just change double by 'unsigned int' (BITPIX 8), 'short' (BITPIX 16)
// 'int' (BITPIX 32) 'long lon' (BITPIX 64), 'float' (BITPIX -32).
-(double*) GetArrayOfDouble
{
int Nelements=[self NPIXEL]; // Metod to extract, from the header
// the number of element into the array
NSLog(@"TOTAL NUMBER OF ELEMENTS [%i]\n",Nelements);
//CREATE THE ARRAY
double (*array)[Nelements];
// Get the total number of bits in the binary data
int Nbit = abs(BITPIX)*GCOUNT*(PCOUNT + Nelements); // GCOUNT and PCOUNT are defined
// into the header
NSLog(@"TOTAL NUMBER OF BIT [%i]\n",Nbit);
int i=0;
//FILL THE ARRAY
double Value;
for(int bit=0; bit < Nbit; bit+=sizeof(double))
{
[Img getBytes:&Value range:NSMakeRange(bit,sizeof(double))];
NSLog(@"[%i]:(%u)%.8G\n",i,bit,Value);
(*array)[i]=Value;
i++;
}
return (*array);
}
不过,我在打印循环的价值从预期值非常不同的(用比较正式的FITS软件)。因此,我认为在的OBJ-C 双击
不使用 IEEE-754 约定还有< STRONG>的OBJ-C INT
不是的补码的。我真的不熟悉这个两公约( IEEE 和补码的),并想知道我该怎么做这种转换是的OBJ-C
However, the value I print in the loop are very different from the expected values (compared using official FITS software). Therefore, I think that the Obj-C double
does not use the IEEE-754 convention as well as the Obj-C int
are not twos-complement. I am really not familiar with this two convention (IEEE and twos-complement) and would like to know how I can do this conversion with Obj-C.
在提前许多感谢任何帮助或信息。
In advance many thanks for any help or information.
推荐答案
非常感谢。这个问题真的涉及到endian和我没有意识到这一点。说实话,我从来没有真正意识到尾数类型的,因为到现在为止,我从来没有遇到这个问题。
Thanks a lot. The problem was really related to the endian and I was not aware of this. Honestly, I was never really aware of the endian type because, up to now, I was never confronted to the problem.
顺便说一句,我找到解决方案,感谢所有为你的话。因为它可以为其他开发人员有用,我会建议code的和平成为可能,这样的NSData转换为原始的,什么都尾数类型。这是我觉得(与基金会和可可框架在OS X 10.5和10.6的工作)的解决方案,它可能不是最好的,所以,需要您自担风险使用;)
By the way, I find the solution, thanks all for your remarks. Because it can be useful for other developer, I will propose a peace of code which allow to convert NSData to primitive, what ever the endian type. This is the solution I find (work with the Foundation and cocoa framework on Os X 10.5 and 10.6) and it may not be the best, so, use at your own risk ;)
// 1- CREATE AN ARRAY OF SIZE Nelements;
int Nelements = XXX;
double (*array)[Nelements];
// 2- Create the swapped double -> a double with the wrong bit order
NSSwappedDouble swappedValue;
// 3- The correct value
double Value;
// 4- Fill your array
int i=0, bit=0;
int BitStep=sizeof(double);
while(i<Nelements)
{
[MyNSData getBytes:&swappedValue range:NSMakeRange(bit,step)];
Value = NSSwapBigDoubleToHost(swappedValue); // or NSSwapLittleDoubleToHost depending of your endian type.
(*array)[i]=Value;
i++; bit+=BitStep;
}
希望这是有用的。
Hope this can be useful.
这篇关于NSData的转换为基本变量与IEEE-754或二进制补码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!