介绍 MySQL字符串转成双的定义函数如下:
这篇文章主要介绍MySQL中隐式转换的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
<强>一、问题描述强>
root@mysqldb 二二12:,,[xucl]祝辞,show create table t1 \ G * * * * * * * * * * * * * * * * * * * * * * * * * * *,1只row * * * * * * * * * * * * * * * * * * * * * * * * * * * ,,,,,,表:t1 Create 表:,Create TABLE  t1, ( “id”,才能varchar (255), DEFAULT NULL ),引擎=InnoDB DEFAULT CHARSET=utf8 1,row set 拷贝;(0.00,sec) root@mysqldb 22:19:,, [xucl]祝辞,select *,得到t1; +--------------------+ |,id ,,,,,,,,,,,,,,, | +--------------------+ |,204027026112927605 | |,204027026112927603 | |,2040270261129276,,| |,2040270261129275,,| |,100,,,,,,,,,,,,,,,| |,101,,,,,,,,,,,,,,,| +--------------------+ 6,rows set 拷贝;(0.00,sec)
奇怪的现象:
root@mysqldb 22:19:,, [xucl]祝辞,select *,得到t1 where id=204027026112927603; +--------------------+ |,id ,,,,,,,,,,,,,,, | +--------------------+ |,204027026112927605 | |,204027026112927603 | +--------------------+ 2,rows set 拷贝;(0.00,sec)
<强>什么鬼,明明查的是204027026112927603,为什么204027026112927605也出来了强>
<强>二、源码解释强>
堆栈调用关系如下所示:
其中<代码>加入::exec() 代码>是执行的入口,<代码> Arg_comparator: compare_real() 代码>是进行等值判断的函数,其定义如下
int Arg_comparator: compare_real () { ,/* ,,,Fix yet another manifestation of 错误# 2338只& # 39;挥发性# 39;will 指导 ,,,gcc 用flush double values out of 80 - bit Intel FPU registers 之前 ,,,performing 从而比较。 ,*/volatile 才能double val1, val2; val1才能=,(*)→val_real (); if 才能;(! (*)→null_value) {才能 ,,,val2=, (* b)→val_real (); ,,,if (! (* b)→null_value) ,,,{ ,,,,,if (set_null) ,,,,,,,老板→null_value=https://www.yisu.com/zixun/0; 如果(val1null_value=1; 返回1; }
比较步骤如下图所示,逐行读取t1表的id列放入val1,而常量204027026112927603存在于缓存中,类型为两类型(2.0402702611292762 e + 17),所以到这里传值给val2后val2=2.0402702611292762 e + 17。
当扫描到第一行时,204027026112927605转成双的值为2.0402702611292762 e17等式成立,判定为符合条件的行,继续往下扫描,同理204027026112927603也同样符合
如何检测字符串类型的数字转成双类型是否溢出呢?<强>这里经过测试,当数字超过16位以后,转成双类型就已经不准确了>强,例如20402702611292711会表示成20402702611292712(如图中val1)
MySQL字符串转成双的定义函数如下:
{ char 才能buf [DTOA_BUFF_SIZE]; double 才能,res; DBUG_ASSERT(才能最终获得!=,NULL ,,, ((str !=, NULL ,,, *最终获得!=,NULL), | | ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(str ==, NULL ,,, *最终获得==,NULL)),,, ,,,,,,,,,,,,,error !=, NULL); res=,才能my_strtod_int (str,,,,错误,,但,,sizeof (buf)); return 才能;(* error ==, 0), ?, res :, (res & lt;, 0, ?, -DBL_MAX :, DBL_MAX); }
真正转换函数<代码> my_strtod_int> 代码位置在时差。c(太复杂了,简单贴个注释吧)