数据转换 问:我在将双精度转为整数时碰上了一个奇怪的事情,这是部分代码: m_barradose.Seek((UINT)(m_dosenum * 10)); Write_serial(0x01, Hex_to_dec((UINT)(m_dosenum * 10))); m_dose_disp_box.SetModify(0); UpdateData(FALSE); 其中 m_dosenum是双精度类型变量,由一个微调控件控制,其中增大/减少步长为 0.1. 因此m_dosenum于0.0开始,然后为0.1, 0.2, 0.3, 0.4,... 等等. 我用调试 器跟踪了下列式子的结果, m_dosenum = 0.70000000000000 (m_dosenum * 10) = 7.0000000000000 ((UINT)(m_dosenum * 10)) = 7 .... 在增加了一个步长后: m_dosenum = 0.80000000000000 (m_dosenum * 10) = 8.0000000000000 ((UINT)(m_dosenum * 10)) = 7 我真的弄不懂为什么最后一个式子没有变化.有趣的是如果将m_dosenum增至0.9, 然 后再减至0.8,那么会显示出正确的结果,有谁能告诉我哪儿错了? 答: 这就是著名的浮点运算错误,如果你仔细观察,就会发现'正确'的0.8事实上还是 有一个很小的误差.如果你圆整一下数据,就不会出错了. ((UINT)((m_dosenum + 0.05) * 10)) 欢迎来到奇妙的浮点运算世界,这里有一个规则特别需要注意:浮点数并不精确. 0.8或者说你在调试器中看到的0.8事实上并不是,有可能是0.79999999999999,然 后圆 整得到了0.8,如果采用截尾法那么你就会看到结果是7! 那该怎么处理呢? 加一个圆整值: 将 (UINT)( m_dosenum * 10 ) 替换为 (UINT)( m_dosenum * 10 + 0.5 ) 出于相同的原因,象 if ( m_double == 2.0 ) 肯定是假的,应该这样写,我通常使用0.00001 if( fabs( m_double - 2.0 )