我正在创建一个允许用户传递double值的函数,然后返回一个UInt16。
这是我的代码:
public static UInt16 Value_To_BatteryVoltage(double value)
{
var ret = ((int)value << 8);
var retMod = (value % (int)value) * 10;
return (UInt16)(ret + retMod);
}
基本上它的作用如下,函数调用:
Value_To_BatteryVoltage(25.10)
将返回:6401
我可以通过以下方式检查结果:
public static double VoltageLevel(UInt16 value)
{
return ((value & 0xFF00) >> 8) + ((value & 0x00FF) / 10.0);
}
这是按预期工作的,但是,如果我这样做:
Value_To_BatteryVoltage(25.11) //notice the 0.11
我得到了错误的结果,因为:
public static UInt16 Value_To_BatteryVoltage(double value)
{
var ret = ((int)value << 8); // returns 6400 OK
var retMod = (value % (int)value) * 10; //returns 0.11 x 10 = 1.1 WRONG!
return (UInt16)(ret + retMod); //returns 6400, because (UInt16)(6400 + 1.1) = 6401 same as 25.10 so I've lost precision
}
所以问题是,有没有办法在不损失精度的情况下进行这种转换?
答案 0 :(得分:0)
如果我理解了这个问题,你想将特征(整数部分)存储在UInt16的前8位。和尾数(小数部分)在第二个8位。
这是一种方法。我把double视为一个字符串并将其拆分为十进制。例如:
public static UInt16 Value_To_BatteryVoltage(double value)
{
string[] number = value.ToString().Split('.');
UInt16 c = (UInt16)(UInt16.Parse(number[0]) << 8);
UInt16 m = UInt16.Parse(number[1]);
return (UInt16)(c + m);
}
这是输出: