1

我正在制作一个允许用户传递双精度值,然后返回 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
    }

所以问题是,有没有办法在不损失精度的情况下进行这种转换?

4

1 回答 1

0

如果我理解这个问题,您希望将特征(整数部分)存储在 UInt16 的前 8 位中。以及第二个 8 位中的尾数(小数部分)。

这是一种方法。我将双精度数视为字符串并将其拆分为小数点。例如:

    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);
    }

这是输出:

代码输出

于 2013-10-09T14:34:29.043 回答