全国服务热线:

15861139266

数字转字符串,苏州PLC培训,苏州上位机培训,苏州机器视觉培训,苏州工业机器人培训,苏州电工培训
发布时间:2023-04-19 16:52:28 点击次数:291

数字转字符串

先看数字转字符串里面算多少位数的/**

 * Returns the number of digits in the base 10 representation of an

 * uint64_t. Useful for preallocating buffers and such. It's also used

 * internally, see below. Measurements suggest that defining a

 * separate overload for 32-bit integers is not worthwhile.

 */


inline uint32_t digits10(uint64_t v) {


#ifdef __x86_64__

  // For this arch we can get a little help from specialized CPU instructions

  // which can count leading zeroes; 64 minus that is appx. log (base 2).

  // Use that to approximate base-10 digits (log_10) and then adjust if needed.


  // 10^i, defined for i 0 through 19.

  // This is 20 * 8 == 160 bytes, which fits neatly into 5 cache lines

  // (assuming a cache line size of 64).


  static const uint64_t powersOf10[20] FOLLY_ALIGNED(64) = {

      1,

      10,

      100,

      1000,

      10000,

      100000,

      1000000,

      10000000,

      100000000,

      1000000000,

      10000000000,

      100000000000,

      1000000000000,

      10000000000000,

      100000000000000,

      1000000000000000,

      10000000000000000,

      100000000000000000,

      1000000000000000000,

      10000000000000000000UL,

  };


  // "count leading zeroes" operation not valid; for 0; special case this.

  if UNLIKELY (!v) {

    return 1;

  }


  // bits is in the ballpark of log_2(v).

  const uint8_t leadingZeroes = __builtin_clzll(v);

  const auto bits = 63 - leadingZeroes;


  // approximate log_10(v) == log_10(2) * bits.

  // Integer magic below: 77/256 is appx. 0.3010 (log_10(2)).

  // The +1 is to make this the ceiling of the log_10 estimate.

  const uint32_t minLength = 1 + ((bits * 77) >> 8);


  // return that log_10 lower bound, plus adjust if input >= 10^(that bound)

  // in case there's a small error and we misjudged length.

  return minLength + (uint32_t) (UNLIKELY (v >= powersOf10[minLength]));


#else

  uint32_t result = 1;

  for (;;) {

    if (LIKELY(v < 10)) return result;

    if (LIKELY(v < 100)) return result + 1;

    if (LIKELY(v < 1000)) return result + 2;

    if (LIKELY(v < 10000)) return result + 3;

    // Skip ahead by 4 orders of magnitude

    v /= 10000U;

    result += 4;

  }

#endif

}

下面那个for loop多友好,上面x86那段是什么鬼!builtin_clzll 是gcc里面的一个函数,具体定义看这里Other Builtins 简单来说就是算有几个开头的0的。这里面的0是2进制的0,所以63-leading zeros就是说二进制里面有几位数。  const uint32_t minLength = 1 + ((bits * 77) >> 8);

这个就是亮点了。高中数学没学好的话,这里强调一下log_10(v) =log_10(2) * log_2(v) (The Change-of-Base Formula)>> 8 就是处以256bits在这里已经是log(2)了+1是因为 0.3010略小于77/256我们继续瞎,现在开始正式转换/**

 * Copies the ASCII base 10 representation of v into buffer and

 * returns the number of bytes written. Does NOT append a \0. Assumes

 * the buffer points to digits10(v) bytes of valid memory. Note that

 * uint64 needs at most 20 bytes, uint32_t needs at most 10 bytes,

 * uint16_t needs at most 5 bytes, and so on. Measurements suggest

 * that defining a separate overload for 32-bit integers is not

 * worthwhile.

 *

 * This primitive is unsafe because it makes the size assumption and

 * because it does not add a terminating \0.

 */


inline uint32_t uint64ToBufferUnsafe(uint64_t v, char *const buffer) {

  auto const result = digits10(v);

  // WARNING: using size_t or pointer arithmetic for pos slows down

  // the loop below 20x. This is because several 32-bit ops can be

  // done in parallel, but only fewer 64-bit ones.

  uint32_t pos = result - 1;

  while (v >= 10) {

    // Keep these together so a peephole optimization "sees" them and

    // computes them in one shot.

    auto const q = v / 10;

    auto const r = static_cast<uint32_t>(v % 10);

    buffer[pos--] = '0' + r;

    v = q;

  }


  // Last digit is trivial to handle

  buffer[pos] = static_cast<uint32_t>(v) + '0';

  return result;

}




1.png

立即咨询
  • 品质服务

    服务贴心周到

  • 快速响应

    全天24小时随时沟通

  • 专业服务

    授权率高,保密性强

  • 完善售后服务

    快速响应需求,及时性服务

直播课程
软件开发基础课程
上位机软件开发课
机器视觉软件开发课
专题课
联系方式
电话:15861139266
邮箱:75607082@qq.com
地址:苏州吴中区木渎镇尧峰路69号
关注我们

版权所有:江苏和讯自动化设备有限公司所有 备案号:苏ICP备2022010314号-1

技术支持: 易动力网络