Decimal vs Double Speed

前端 未结 7 1062
暗喜
暗喜 2020-11-27 13:03

I write financial applications where I constantly battle the decision to use a double vs using a decimal.

All of my math works on numbers with no more than 5 decimal

7条回答
  •  时光取名叫无心
    2020-11-27 14:02

    There are two separable issues here. One is whether the double has enough precision to hold all the bits you need, and the other is where it can represent your numbers exactly.

    As for the exact representation, you are right to be cautious, because an exact decimal fraction like 1/10 has no exact binary counterpart. However, if you know that you only need 5 decimal digits of precision, you can use scaled arithmetic in which you operate on numbers multiplied by 10^5. So for example if you want to represent 23.7205 exactly you represent it as 2372050.

    Let's see if there is enough precision: double precision gives you 53 bits of precision. This is equivalent to 15+ decimal digits of precision. So this would allow you five digits after the decimal point and 10 digits before the decimal point, which seems ample for your application.

    I would put this C code in a .h file:

    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));
    }
    

    There are probably a few rough spots but that should be enough to get you started.

    No overhead for addition, cost of a multiply or divide doubles.

    If you have access to C99, you can also try scaled integer arithmetic using the int64_t 64-bit integer type. Which is faster will depend on your hardware platform.

提交回复
热议问题