这里有两个可分离的问题。一个是 double 是否有足够的精度来保存你需要的所有位,另一个是它可以准确地表示你的数字。
至于确切的表示,您应该谨慎,因为像 1/10 这样的精确十进制分数没有精确的二进制对应物。但是,如果您知道您只需要 5 位十进制数字的精度,则可以使用缩放算术,在其中对数字乘以 10^5 进行运算。因此,例如,如果您想准确表示 23.7205,您可以将其表示为 2372050。
让我们看看是否有足够的精度:双精度为您提供 53 位精度。这相当于 15+ 个十进制数字的精度。因此,这将允许您在小数点后有 5 位数字,在小数点前有 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,您还可以尝试使用int64_t
64 位整数类型的缩放整数算术。哪个更快取决于您的硬件平台。