整型转字符串(convert int to char)优化实践——一个意外的BUG
2017-05-17 22:21
274 查看
convert_int_to_char函数在使用时出现过一个BUG。
当使用值是13200020099时,返回的字符串是"13200020111",结果是错误的。
在gcc编译器里,使用32位整型时对一个数value除于100时会默认优化成先将value乘以0x51eb851f再右移37位;而使用long long类型时就不做任何优化,即便做除于100的value实际是小于32位整型的最大值也是如此。
在函数covert_int_to_char函数里有部份代码有除以100的逻辑,使用了相同的优化方式。在代码中限制value小于0x31fffffff时使用乘以0x51eb851f再右移37位的优化方式。这里使用0x31fffffff这个值是为了避免value乘以0x51eb851f时造成溢出。
乘以0x51eb851f再右移37位的做法,等价于先乘以1374389535再除以137438953472,也等价乘以一个比0.01稍大一点点数。
通过二分法去探测边界,可以找到。
当value大于4908534098时,尾数为99的数字乘以这个比0.01稍大一点点的数字就会产生进位导致结果错误。在4908534098到0x31fffffff这个区间内直接使用这种优化,尾数是99的整型结果一定是错误。
在value小于4908534098才使用将value乘以0x51eb851f再右移37位的优化能保证结果的正确。
当使用值是13200020099时,返回的字符串是"13200020111",结果是错误的。
在gcc编译器里,使用32位整型时对一个数value除于100时会默认优化成先将value乘以0x51eb851f再右移37位;而使用long long类型时就不做任何优化,即便做除于100的value实际是小于32位整型的最大值也是如此。
在函数covert_int_to_char函数里有部份代码有除以100的逻辑,使用了相同的优化方式。在代码中限制value小于0x31fffffff时使用乘以0x51eb851f再右移37位的优化方式。这里使用0x31fffffff这个值是为了避免value乘以0x51eb851f时造成溢出。
乘以0x51eb851f再右移37位的做法,等价于先乘以1374389535再除以137438953472,也等价乘以一个比0.01稍大一点点数。
通过二分法去探测边界,可以找到。
>>> print (4908533999 * 1374389535/ 137438953472) 49085339 >>> print (4908534098 * 1374389535/ 137438953472) 49085340 >>> print (4908534099 * 1374389535/ 137438953472) 49085341
当value大于4908534098时,尾数为99的数字乘以这个比0.01稍大一点点的数字就会产生进位导致结果错误。在4908534098到0x31fffffff这个区间内直接使用这种优化,尾数是99的整型结果一定是错误。
在value小于4908534098才使用将value乘以0x51eb851f再右移37位的优化能保证结果的正确。
相关文章推荐
- 整型转字符串(convert int to char)优化实践
- 【C编程练习】2013华为校园招聘机试题9月10日题1:把整数转换成字符串 void ConvertIntToStr(int nVal, char* pStr);
- c#--编写一个名称为MyClass一个类,在该类中编写一个方法,名称为CountChar,返回值为整型,参数两个,第一个参数可以是字符串、整数、单精度、双精度,第二个参数为字符,方法功能返回第二个参
- 我用c#写了一个测试样例,分析了int,char,datetime和varchar的日志情况而且没有考虑null和空字符串的保存,希望感兴趣的朋友能和我一起交流打造属于自己的日志分析工具
- CString、char、string、int、_bstr_t、CTime、COleDateTime相互转换&判断一个字符串是一个浮点数
- [置顶] C语言,从字符串中提取一个字符串,int substr(char dst[], char src[],int start,int len)
- 【算法和数据结构】_16_小算法_IntToStr: 将整型数据转换为字符串
- JavaScript中prototype(原型)给字符串对象添加一个toCharArray的方法,reverse(翻转)的 方法
- 编写一个函数,有如下函数原型: 函数:int continum(char *intputstr,char *outputstr). 给一个字符串,要求找到里面连续的串,并且串的长度是所有连续串中
- 将整型转换为枚举型(convert int to enum)
- python:字符串和数字拼接 (TypeError: Can't convert 'int' object to str implicitly)
- LoadCursorA' : cannot convert parameter 2 from 'const int' to 'const char *
- php 长整型转字符串 (convert long to string)
- 字符串转换为数字:String:convert a string to int
- 数字转换为字符串:String:convert an int to a string
- int ascii_to_integer(char *str); 这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- selenium--unittest字符串/整型问题Can't convert 'int' object to str implicitly提示解决方法
- 编写一个函数,它从一个字符串中提取一个子字符串。函数原型如下: Int substr(char dst[], char src[],int start, int len) {} 目标是:从src数组
- error C2664: 'atof' : cannot convert parameter 1 from 'int' to 'const char *'
- c++ int to string 整型到字符串