Decimal vs Double速度
Decimal vs Double速度
我编写金融应用程序,经常要决定使用double还是decimal。
我的所有数学计算都在小于或等于100,000且不超过5个小数位的数字上进行。我有一种感觉,所有这些都可以表示为double,而不会出现舍入误差,但我从来没有确定过。
我会继续从decimal向double转换,以获得明显的速度优势,但最终我仍然使用ToString方法将价格传输到交易所,并需要确保它始终输出我期望的数字。(89.99而不是89.9900000001)
问题:
- 速度优势真的像天真的测试所表明的那样大吗? (约100倍)
- 有没有办法保证ToString的输出是我想要的?我的数字始终可以表示,这能保证吗?
更新:在我的应用程序运行之前,我必须处理大约10亿次价格更新,并且我现在已经实现了decimal以获得明显的保护作用,但它需要大约3个小时才能启动,如果改用double,将极大地缩短启动时间。有没有安全的方法使用double?
admin 更改状态以发布 2023年5月21日
这里有两个可以分离出的问题。一个是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 的缩放整数算术。哪个更快将取决于你的硬件平台。