Native C#:从其位表示重构十进制数

时间:2015-01-12 03:39:18

标签: c#

typedef struct
{
    union {
        uint32_t ss32;    
        struct {
            unsigned int reserved1 : 16;
            unsigned int scale : 8;
            unsigned int reserved2 : 7;
            unsigned int sign : 1;
        } signscale;
    } u;
    uint32_t hi32;
    uint32_t lo32;
    uint32_t mid32;
} decimal_repr;

鉴于Decimal结构,我如何将其内部数据重建为人类可读的数字,例如123456.987654000123456?我找不到任何解释十进制结构的文档(左移或右移多少位,它的分数,尾数等)。

我还发现Decimal类会链接到libdec,但我无法在项目源代码中的任何位置找到lib。如果有的话,我肯定只想重复使用它。

修改

我仍然坚持两个问题:

  1. 如果我使用上面的公式来计算最终输出结果,那么它将看起来像我回归到普通内置类型(例如10000 / 3.0 = 333.3333)的正常计算(mult,div,pow)默认情况下,编号会限制位数。
  2. 在十进制类中,我只有4个私有成员(lo,hi,mid,flags),其中flags是在上述结构中定义的16位左移值scale; AND如果输入值为负,则必须屏蔽标志或将其最低有效位值设置为0x8000000。现在给定上面的struct数据,我想初始化Decimal类成员,尤其是flags。 当然我可以将scale值右移16位以获得flags,但是如果sign是1,这是负输入值,我对于逆运算是愚蠢的 flags|=0x8000000。也就是说,从先前移位的比例中消除最低有效位值以获得原始flags

1 个答案:

答案 0 :(得分:3)

( - 1)^符号*(hi32 * 2 ^ 64 + mid32 * 2 ^ 32 + lo32)/ 10 ^规模

  

十进制数的二进制表示由1位符号,96位整数和用于除以整数的比例因子组成,并指定它的哪个部分是小数。缩放因子隐式地表示从0到28的指数10。MSDN

编辑:

  1. 你必须以某种方式处理长算术。十进制是最大的内置数字类型,因此您不能在其他内置类型的单个变量中表示所有可能的十进制值。
  2. 不完全理解你的问题。 decimal_repr直接对应Decimal结构,它具有相同的相同字段。 flags对应ss32hihi32lolo32midmid32。因此,如果你有数据结构,那么你已经有了Decimal结构,不需要转换。如果您想从sing清除flags标记,那么您可以执行此操作:flags&=0x7fffffff