1

ユーザーが 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
    }

問題は、精度を失うことなくこの種の変換を行う方法があるかどうかです。

4

1 に答える 1

0

質問が理解できれば、UInt16 の最初の 8 ビットに Characteristic (整数部分) を格納する必要があります。そして、2 番目の 8 ビットの仮数部 (小数部)。

これは 1 つの方法です。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);
    }

出力は次のとおりです。

コード出力

于 2013-10-09T14:34:29.043 に答える