假定三个字节放在byte[] data={0x03,0xDF,0xCF},详细的分别为(这是一位名为gomoku的朋友给出的解释):
0 1 2
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- + E E E E E s s s s s s s s s s s s s s s s s0 0 0 0 0 0 1 1 (03)
1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 (DF CF)
第一位 (-) 是这个数的符号,0为正,
第二位(+) 是指数的符号,
EEEEEE 是指数,
ss...s 是小数部分. (一个 1 通常被加做前缀变为 1.sssssssssssssssss) 例如:
03 DF CF = (+)1.1101111111001111 ^( +000011 ) = 1.8742523193359375^3 = 6.58 我想用C#编程将上面的byte[]型数组data换成double型结果x要怎样实现呢?我对熟制转换这部分很糊涂,希望大家帮帮忙了!!小妹在此谢过了!~
0 1 2
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- + E E E E E s s s s s s s s s s s s s s s s s0 0 0 0 0 0 1 1 (03)
1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 (DF CF)
第一位 (-) 是这个数的符号,0为正,
第二位(+) 是指数的符号,
EEEEEE 是指数,
ss...s 是小数部分. (一个 1 通常被加做前缀变为 1.sssssssssssssssss) 例如:
03 DF CF = (+)1.1101111111001111 ^( +000011 ) = 1.8742523193359375^3 = 6.58 我想用C#编程将上面的byte[]型数组data换成double型结果x要怎样实现呢?我对熟制转换这部分很糊涂,希望大家帮帮忙了!!小妹在此谢过了!~
0 1 2
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- + E E E E E E s s s s s s s s s s s s s s s s 0 0 0 0 0 0 1 1 (03)
1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 (DF CF)
我的这个是24 bit float is not common and might require your own manipulation.
我不应该转成double型,应该是float型
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
- + E E E E E s s s s s s s s s s s s s s s s s
判断-位,然后拿到ssss那些小数部分,转换成float类型,然后拿到eeee指数部分,然乎利用Math类计算指数,得到最后的值,不用我贴具体代码了吧
{
static void Main()
{
byte[] data = { 0x03,0xDF,0xCF };
Console.WriteLine(ToSingle3(data, 0));
}
// 返回由字节数组中指定位置的三个字节转换来的单精度浮点数。
static float ToSingle3(byte[] value, int startIndex)
{
if (value == null) throw(new ArgumentNullException());
if (startIndex < 0 || startIndex > value.Length - 3) throw(new ArgumentOutOfRangeException());
double t = 1; // 尾数
double s = 0.5;
byte b = value[startIndex + 1];
for (int i = 0; i < 8; i++)
{
if ((b & 0x80) != 0) t += s;
b <<= 1;
s /= 2;
}
b = value[startIndex + 2];
for (int i = 0; i < 8; i++)
{
if ((b & 0x80) != 0) t += s;
b <<= 1;
s /= 2;
}
b = value[startIndex];
int sign0 = (b & 0x80) == 0 ? 1 : -1; // 尾数的符号
int sign1 = (b & 0x40) == 0 ? 1 : -1; // 指数的符号
int E = (b & 0x3F) * sign1; // 指数
return (float)(Math.Pow(t, E) * sign0);
}
}
/* 程序输出:
6.583914
*/
public static string HtoS(int num)
{
string tmp = Convert.ToString(num, 2); //用来计算符号,指数符号,和指数
if (tmp.Length < 8)
tmp = new string('0', 8 - tmp.Length) + tmp;
return tmp;
}
public static void Main()
{
string tmp1 = HtoS(0x03);
bool flag1 = tmp1[0] == '1' ? true : false; //符号
bool flag2 = tmp1[0] == '1' ? true : false; //指数符号
//指数
int power = Convert.ToInt32(tmp1.Substring(2, 6), 2);
if (flag2)
power = 0 - power; //小数部分
string tmp2 = HtoS(0xDF) + HtoS(0xCF);
double decimal_fraction = 1;
for (int i = 0,j=-1; i < 16; ++i,--j)
{
decimal_fraction += Convert.ToInt32(tmp2[i].ToString()) * Math.Pow(2, j);
}
double result = Math.Pow(decimal_fraction, power);
if (flag1)
result = 0 - result;
Console.WriteLine(result);
}
//16进制转2进制字符串
public static string HtoS(int num)
{
return Convert.ToString(num, 2).PadLeft(8, '0');
}
另:指数符号应该是 tmp[1],而不是 tmp[0]:
bool flag2 = tmp1[1] == '1' ? true : false; //指数符号
bool flag1 = tmp1[0] == '1'; //符号
bool flag2 = tmp1[1] == '1'; //指数符号