ここには 2 つの分離可能な問題があります。1 つは double が必要なすべてのビットを保持するのに十分な精度を持っているかどうか、もう 1 つは数値を正確に表現できるかどうかです。
正確な表現に関しては、1/10 のような正確な 10 進数には正確な 2 進法がないため、注意が必要です。ただし、小数点以下 5 桁の精度しか必要ないことがわかっている場合は、数値に 10^5 を掛けた演算を行うスケーリング演算を使用できます。たとえば、23.7205 を正確に表したい場合は、2372050 と表します。
十分な精度があるかどうか見てみましょう。倍精度では 53 ビットの精度が得られます。これは、10 進数で 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));
}
おそらくいくつかの荒い点がありますが、それはあなたが始めるのに十分なはずです.
加算のオーバーヘッドがなく、乗算または除算のコストが 2 倍になります。
C99 にアクセスできる場合は、int64_t
64 ビット整数型を使用してスケーリングされた整数演算を試すこともできます。どちらが速いかは、ハードウェア プラットフォームによって異なります。