【问题标题】:How do I convert a double to a proprietary floating point format in C#?如何在 C# 中将双精度数转换为专有浮点格式?
【发布时间】:2014-09-09 13:57:17
【问题描述】:

我有一个 20 位专有浮点格式定义为:

Bits: 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
Use:   s  e  e  e  e  e  m  m  m  m  m  m  m  m  m  m  m  m  m  m 

Where 
s = sign, (1=negative, 0=positive)
e = exponent, (10^0 to 10^31)
m = mantissa, (2^0 to 2^14-1, 0 to 16383)

此位分配给出了从 -16383 X 10^31 到 +16383 X 10^31 的值范围。

现在,如果我在 C# 中有一个双精度值(或最好的十进制),我如何将此数字转换为这种专有的浮点格式?有一个十进制构造函数 - Decimal(int lo, int mid, int hi, bool isNegative, byte scale) - 可以帮助我将此格式转换为小数,但不能反过来。交给你了……

【问题讨论】:

  • 构造函数的反面是decimal.GetBits(value) - 但是,我不确定这会帮助你获得尾数/指数等;简单地说:decimal 那样不行
  • 当我进行摩托罗拉快速浮点到 IEEE 的转换时,我使用显式布局创建了一个具有浮点和整数字段的结构,因此它们重叠。然后根据需要对符号、指数和尾数进行掩码、移位或以其他方式摆弄。正如 Marc 所建议的,十进制可能不是开始的地方。
  • 请注意,十进制不是开始的地方,它只是我在尝试将数字转换为这种奇怪格式时遇到的问题。
  • @MarcGravell:实际上,十进制的工作方式或多或少与上述专有格式相同。十进制只有 0-28 的负数(其中 28 表示 10^-28),这也是十进制数。应该很容易将其转换为给定的格式。
  • 等一下:上面的格式中没有分数吗?只有整数?

标签: c# floating-point type-conversion


【解决方案1】:

这是进行转换的一种方法,(可能不是最佳的):

public static class Converter
{
    private const int cSignBit = 0x80000; // 1 bit
    private const int cExponentBits = 0x7C000; // 5 bits
    private const int cMaxExponent = 0x1F; // 5 bits
    private const int cMantissaBits = 0x03FFF; // 14 bits
    private const double cExponentBase = 10;
    private const int cScale = 100000;

    public static int DoubleToAmount(double aValue)
    {
        // Get the sign
        bool lNegative = (aValue < 0);

        // Get the absolute value with scaling
        double lValue = Math.Abs(aValue) * cScale;

        // Now keep dividing by 10 to get the exponent value
        int lExponent = 0;
        while (Math.Ceiling(lValue) > cMantissaBits)
        {
            lExponent++;
            if (lExponent > cMaxExponent)
                throw new ArgumentOutOfRangeException("Cannot convert amount", (Exception)null);
            lValue = lValue / (double)cExponentBase;
        }

        // The result that is left rounded up is the mantissa
        int lMantissa = (int)Math.Ceiling(lValue);

        // Now we pack it into the specified format
        int lAmount = (lNegative ? cSignBit : 0) + lExponent * (cMantissaBits + 1) + lMantissa;

        // And return the result
        return lAmount;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2018-04-26
    • 1970-01-01
    相关资源
    最近更新 更多