Decimal vs Double速度

19 浏览
0 Comments

Decimal vs Double速度

我编写金融应用程序,经常要决定使用double还是decimal。

我的所有数学计算都在小于或等于100,000且不超过5个小数位的数字上进行。我有一种感觉,所有这些都可以表示为double,而不会出现舍入误差,但我从来没有确定过。

我会继续从decimal向double转换,以获得明显的速度优势,但最终我仍然使用ToString方法将价格传输到交易所,并需要确保它始终输出我期望的数字。(89.99而不是89.9900000001)

问题:

  1. 速度优势真的像天真的测试所表明的那样大吗? (约100倍)
  2. 有没有办法保证ToString的输出是我想要的?我的数字始终可以表示,这能保证吗?

更新:在我的应用程序运行之前,我必须处理大约10亿次价格更新,并且我现在已经实现了decimal以获得明显的保护作用,但它需要大约3个小时才能启动,如果改用double,将极大地缩短启动时间。有没有安全的方法使用double?

admin 更改状态以发布 2023年5月21日
0
0 Comments

这里有两个可以分离出的问题。一个是double是否具有足够的精度来容纳所有所需的位,另一个是是否可以精确地表示你的数字。

关于精确表示,你谨慎是正确的,因为像1/10这样的精确十进制小数没有精确的二进制对应物。然而,如果你知道只需要5个十进制数字的精度,你可以使用缩放算术,在其中通过乘以10^5来操作数字。例如,如果你想要精确表示23.7205,你可以将它表示为2372050。

让我们看看是否有足够的精度:双精度浮点数给你53位精度,相当于15+十进制数字的精度。因此,这可以允许你在小数点后面使用五个数字,在小数点前面使用10个数字,这对于你的应用程序似乎足够了。

我会将这个C代码放在.h文件中:

typedef double scaled_int;
#define SCALE_FACTOR 1.0e5  /* number of digits needed after decimal point */
static inline scaled_int adds(scaled_int x, scaled_int y) { return x + y; }
static inline scaled_int muls(scaled_int x, scaled_int y) { return x * y / SCALE_FACTOR; }
static inline scaled_int scaled_of_int(int x) { return (scaled_int) x * SCALE_FACTOR; }
static inline int intpart_of_scaled(scaled_int x) { return floor(x / SCALE_FACTOR); }
static inline int fraction_of_scaled(scaled_int x) { return x - SCALE_FACTOR * intpart_of_scaled(x); }
void fprint_scaled(FILE *out, scaled_int x) {
  fprintf(out, "%d.%05d", intpart_of_scaled(x), fraction_of_scaled(x));
}

也许还有一些不完善的地方,但这应该足够让你开始了。

没有加法开销,乘法或除法的成本会增加。

如果你可以访问 C99,你也可以尝试使用64位整数类型 int64_t 的缩放整数算术。哪个更快将取决于你的硬件平台。

0
0 Comments

    \n

  1. 浮点运算通常会更快,因为它直接得到硬件支持。目前几乎没有广泛使用的硬件支持十进制运算(虽然这正在改变,见评论)。
  2. \n

  3. 金融应用程序应该总是使用十进制数,由于在金融应用程序中使用浮点数而导致的恐怖故事数不胜数,你可以在谷歌搜寻中找到许多这样的例子。
  4. \n

  5. 虽然十进制运算可能比浮点运算慢很多,但除非你花费了大量时间处理十进制数据,否则对你程序的影响很可能是可以忽略的。像往常一样,在你开始担心差异之前,请进行适当的性能分析。
  6. \n

0