如何将int64-fixed-point转换为double?

时间:2014-01-12 06:10:52

标签: c++

我正在使用int64来存储我的decimal值。在金融方面,我需要“确切”的值,因此我必须使用base 10而不是base 2。我全球都有这个:

typedef int64_t myDecimal;
const int DECIMALS_GLOBAL = 10;

我将每个值“复用”到10^10 例如

1 is 10000000000
0.001 is 10000000

现在我需要将myDecimal转换为double。这听起来很简单我只能((double) myDecValue) / 10^10,但这很有风险,因为double很可能无法存储“大”的int64值。所以我写了这样的函数:

int64_t posPow10_64[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000,
100000000000,
1000000000000,
10000000000000,
100000000000000,
1000000000000000
};

double Utils::MyDecimalToDouble(myDecimal value) {
    int beforeDot = value / posPow10_64[DECIMALS_GLOBAL];
    return (double) beforeDot + ((double) (value - beforeDot * posPow10_64[DECIMALS_GLOBAL])) / posPow10_64[DECIMALS_GLOBAL];
}

我认为这个函数的风险较小,因为我将其转换为双倍小的值,但这个函数看起来非常复杂并且可能很慢。

你会推荐什么,我的问题是常见的,如何转换为双倍快速简单和安全?

1 个答案:

答案 0 :(得分:2)

关于“很可能双人无法存储"大" int64“,这取决于你的意思是完全。由于您正在执行十进制固定点,因此除非实现的double类型恰好为十进制,否则您拥有的大部分值都无法准确存储(它原则上可以是,不像必须是二进制的整数)。例如,0.2不能与任何普通double类型完全一致地存储,因为它不能完全表示为2的幂之和。

但是,如果它无法准确存储,则无法准确存储,并且没有多少智能转换设备可以解决这个问题。

通常double是64位IEEE浮点,精度大约为52位,范围远大于64位整数,所以幅度没问题。


总结一下,你可以double(myDecValue) / 10000000000(注意10^10是一个小级xor表达式。)