读源码学MYSQL系列(二)decimal存储转化函数decimal2bin

本文深入解析MySQL中decimal类型的存储方式,通过分析decimal2bin函数,了解decimal如何转化为二进制形式。内容包括:decimal的存储结构、decimal2bin函数的思路、前置0处理、整数和小数部分的空间检查及数值转换过程。
摘要由CSDN通过智能技术生成

问题来源

  高精度计算是计算机工程实践中非常重要的内容,在涉及到精确计算的项目中,思考过数据库的设计。因而比较好奇MYSQL中是如何实现对decimal的支持的。本文通过源码阅读,分析理解decimal的存储及各种运算转化。参考源代码:

https://github.com/google/mysql/blob/master/include/decimal.h

https://github.com/twitter-forks/mysql/blob/master/strings/decimal.c

基础准备

首先,在头文件decimal.h中定义了基本结构体和类型:

typedef int32 decimal_digit_t;

MYSQL采取4字节为一组来存储高精度小数,可以存储9位十进制数字。不足9位部分仍然使用4字节存储。

typedef struct st_decimal_t {
   
  int    intg, frac, len;
  my_bool sign;
  decimal_digit_t *buf;
} decimal_t;

其中,各个字段含义如下:

intg: 整数,十进制整数部分位数
frac: 整数,十进制小数部分位数
sign: 布尔,false表示正数,true表示负数
buf: int32类型数组,每个int32存储9位十进制数字
len: 数组buf的长度

还有一些其他的宏定义如下:

typedef decimal_digit_t dec1;
typedef longlong      dec2;

#define DIG_PER_DEC1 9
#define DIG_MASK     100000000
#define DIG_BASE     1000000000
#define DIG_MAX      (DIG_BASE-1)
#define DIG_BASE2    ((dec2)DIG_BASE * (dec2)DIG_BASE)
#define ROUND_UP(X)  (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
static const dec1 powers10[DIG_PER_DEC1+1]={
   
  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
static const int dig2bytes[DIG_PER_DEC1+1]={
   0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
static const dec1 frac_max[DIG_PER_DEC1-1]={
   
  900000000, 990000000, 999000000,
  999900000, 999990000, 999999000,
  999999900, 999999990 };

存储转化函数decimal2bin

  该函数将decimal_t类型的结构体转化为二进制形式。下面结合源代码说明,为了便于理解,将整个函数按照功能顺序拆分成几个模块分析。

思路说明

  前文说过,decimal是采用4字节来存储9位整数的,该函数主要围绕着该思路进行。对于任意一个小数,可以进行如下拆分:

不足9位部分|9位整数(重复多次)|小数点|9位小数(重复多次)|不足9位部分

函数声明

int decimal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值