zoukankan      html  css  js  c++  java
  • 整型转字符串(convert int to char)优化实践——一个意外的BUG

    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稍大一点点数。

    通过二分法去探测边界,可以找到。

    >>> 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位的优化能保证结果的正确。

  • 相关阅读:
    关于CQRS(老外经典好文)
    关于Autofac的使用陷阱
    文件写入文件分布式系统(asp.net C#)
    NET Framework 4.5.2
    asp.net开源
    关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
    sql SELECT时的with(nolock)选项说明
    树形结构的数据库表Schema设计
    C#操作符??和?:
    Byte[]和BASE64之间的转换
  • 原文地址:https://www.cnblogs.com/ohmhong/p/6869846.html
Copyright © 2011-2022 走看看