最近看别人的程序,这个地方看不明白,但我知道他是要把分、秒、毫秒变成一个值,最后用2个字节表示。按我的思路,应该是都化成毫秒: 1mm*60*1000+0ss*1000+ms*10,那么这里应该得到的值是60000,但是又觉得不对,因为如果是59分59秒xx毫秒,那就3个字节都装不下但是他却是这么写的:
lDelay = (ushort)((edtTimeDelay.Minute << 10) + (edtTimeDelay.Second << 4) + (edtMS.Value / 10));
也就是先用分钟左移10,秒钟左移4,毫秒除以10,然后3段相加,最后得到的值是1024他还原的时候是这么写的:
                edtTimeDelay.Minute = Convert.ToUInt16( lTime >> 10;
                edtTimeDelay.Second = (  Convert.ToUInt16 (lTime >> 4) % 0x40;
                edtMS.Value = Convert.ToUInt16 (lTime % 16 * 10;想请哪位大神给解释一下,这是怎么一种操作?不胜感谢!!

解决方案 »

  1.   

    总共 16 bit
    10~15bit,6bit->表示分钟*n,n->(0,63)
    4~9bit,6bit->表示秒*n,n->(0,63)
    0~3bit,4bit->表示10毫秒*n,n->(0,15)因为位不重合,所以可以相加,解析的时候就是反向的移位操作.
    取秒的时候%0x40,是为了取模,因为当右移4bit之后,低位的6位刚好表示秒,但因为高位有分钟影响,
    取模(0x40 == 0b01000000)恰好可以抵消高位的影响,但其实更简洁的操作应该是做个与操作(&0x3F),而不是取模
    取毫秒一样道理,不累述.
      

  2.   

    c++的人臭毛病,早期c++的因为内存稀少,所以锱铢必较。所以他们喜欢做数据压缩,因为分钟0-59 最大59用二进制表示为“0011 1011”所以他觉着多2bit浪费,他一个ushort是16位 ,他说那个用6bit就行,把这个6bit放到最顶上,就是16-6=10
    变成了“1110110000000000”,他用同样的方式可以处理秒现在还剩10bit可以用,10-6=4所以移动4位,现在已经用了12位。16-12=4也就是还能使用4bit去表示毫秒(0-999)他发现4bit表达不了,只好去损精度了,除10ps:最后的毫秒实在不像话啊,(lTime % 16 * 10;)也就只能表达150了
      

  3.   

    这两个byte不够啊 像3楼说的似的 ms表示不全啊
      

  4.   

    小时和分钟楼上的都答完了,
    关于毫秒,我觉得,它在转换时就 /10 了,明显是舍弃进度到100ms,也就是你在输入框输入81~89,到下次进来时,就变为80了,配合UI,每次点击步进10,就说得过去了。
      

  5.   

    其实这是纠结了,正常来说PLC的那边的更喜欢用BCD码,虽然没这压缩高,但通行大家一看就能解。