文章目录
1.作用
为保证小数精度不丢失,数据库表使用 DECIMAL 类型,服务代码中使用,比如 Golang 第三方库 https://github.com/shopspring/decimal。接口协议可以使用 string 表示。
从 DB 存储,服务数据计算与前端接口返回,全链路保证小数精度不会丢失。
DECIMAL 类型另外一个作用就是可以存储非常大的数字,并且在计算时不会出现精度损失。
2.实现原理
各类语言及数据库一般都提供了DECIMAL 类型的支持,一般是以一个 struct 来表示一个 DECIMAL 类型。
比如 MySQL 的实现是:
c
typedef int32 decimal_digit_t;
struct decimal_t {
int intg, frac, len;
bool sign;
decimal_digit_t *buf;
};
Golang 库 github.com/shopspring/decimal 的 DECIMAL 类型定义如下:
go
// Decimal represents a fixed-point decimal. It is immutable.
// number = value * 10 ^ exp
type Decimal struct {
value *big.Int
// NOTE(vadim): this must be an int32, because we cast it to float64 during
// calculations. If exp is 64 bit, we might lose precision.
// If we cared about being able to represent every possible decimal, we
// could make exp a *big.Int but it would hurt performance and numbers
// like that are unrealistic.
exp int32
}
参考文献
13.1.3 Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC
Decimal类型设计方法 - 知乎