我用C#编API函数与外部设备进行串口通信,当我发出命令后得到以下信息:
7E 01 01 FF 09 7F F0 00 03 DF CF 05 CB 33 09 0D 设备说明书里写的返回数据为:
序号: 1 2 3 4 5 6 7 8
字节数:1 1 1 1 1 9 1 1
格式为:7EH 01H 01H FFH 0CH INFOH XXXX 0DH
INFO为返回的数据,每三个字节为一个数据,依次为:A1,A2,A3
测量数据为三字节浮点数:
BYTE1 BYTE2 BYTE3
阶码 原码
BIT7 BIT6 BIT8 BIT4 BIT3 BIT2 BIT1 BIT0
数符 阶符 阶
我想将上面蓝色的三个字节转换成十进制,仪器的显示屏上显示是6.99,
请问高手,如何才能将这三个字节转化为我要的这个数据呢?请帮帮忙!
7E 01 01 FF 09 7F F0 00 03 DF CF 05 CB 33 09 0D 设备说明书里写的返回数据为:
序号: 1 2 3 4 5 6 7 8
字节数:1 1 1 1 1 9 1 1
格式为:7EH 01H 01H FFH 0CH INFOH XXXX 0DH
INFO为返回的数据,每三个字节为一个数据,依次为:A1,A2,A3
测量数据为三字节浮点数:
BYTE1 BYTE2 BYTE3
阶码 原码
BIT7 BIT6 BIT8 BIT4 BIT3 BIT2 BIT1 BIT0
数符 阶符 阶
我想将上面蓝色的三个字节转换成十进制,仪器的显示屏上显示是6.99,
请问高手,如何才能将这三个字节转化为我要的这个数据呢?请帮帮忙!
24 bit float is not common and might require your own manipulation.
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)
the first bit (-) is the sign of the number,
the second bit (+) is the sign of exponent,
EEEEEE are the exponent,
ss...s are the fraction. (an 1 is usually prefixed to become: 1.sssssssssssssssss)For example:
03 DF CF = (+)1.1101111111001111 ^( +000011 ) = 1.8742523193359375^3 = 6.58why the calculation is not 6.99 but 6.58, you might need to check your hardware manual for more details.
0.1 = 0.5
0.01 = 0.25
0.001 = 0.125
0.0001 = 0.0625
假定上面那三个字节放在byte[] data={0x03,0xDF,0xCF},最后转换出的结果放在double PH里面
实在谢谢你了!!
{
static void Main()
{
byte[] data = { 0x7E, 0x01, 0x01, 0xFF, 0x09, 0x7F, 0xF0, 0x00, 0x03, 0xDF, 0xCF, 0x05, 0xCB, 0x33, 0x09, 0x0D };
Console.WriteLine(ToSingle3(data, 8));
}
// 返回由字节数组中指定位置的三个字节转换来的单精度浮点数。
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
*/
03 DF CF = (+)1.1101111111001111 * 2^( +000011 ) = 1.8742523193359375 * 2^3 = 14.99两种方法都不是你要的6.99,所以上次让你核查一下用户手册,不知结果如何?后面这种方法比较接近IEEE-745,把3字节凑成4字节浮点数就可以得到结果了。
如果你确认是后面这种方法,转换代码参考如下:
static float From24bit(byte b1, byte b2, byte b3)
{
int exponent = b1 & 0x2F;
exponent = (b1 & 0x40) == 0x40 ? (127 - exponent) : (127 + exponent); int tmp = BitConverter.ToInt32( new byte[]{0, b3, b2, 0}, 0) >> 1;
tmp = tmp | (exponent << 23) | ((b1 & 0x80) << 24); return BitConverter.ToSingle( BitConverter.GetBytes( tmp ), 0 );
} static void Main(string[] args)
{
float f = From24bit( 0x03, 0xDF, 0xCF ); //14.9940186
}