【问题标题】:Append digit to an int without converting to string?将数字附加到 int 而不转换为字符串?
【发布时间】:2010-10-29 01:50:31
【问题描述】:

有没有一种安全的方法可以在整数末尾添加一个数字而不将其转换为字符串并且不使用字符串流?

我试图用谷歌搜索这个答案,大多数解决方案都建议将其转换为字符串并使用字符串流,但我想将其保留为整数以确保数据完整性并避免转换类型。
我还阅读了一个解决方案,建议将 int 乘以 10,然后添加数字,但这可能会导致整数溢出。
这是安全的还是有更好的方法来做到这一点?如果我这样做乘以 10 并添加数字解,我应该采取哪些预防措施?

【问题讨论】:

    标签: c++ variables append


    【解决方案1】:

    您最好的选择是乘以 10 并加上该值。你可以这样做a naive check

    assert(digit >= 0 && digit < 10);
    newValue = (oldValue * 10) + digit;
    if (newValue < oldValue)
    {
        // overflow
    }
    

    【讨论】:

    • 溢出检查错误。例如,4772185889 - 2^32 = 477218593,大于 477218588。
    • 我同意,我链接到您可以在哪里获得不那么简单的实现。
    • 我稍后输入了一个答案,它有一个非常快速的溢出检查,总是有效的。
    【解决方案2】:

    防止溢出:

    if ((0 <= value) && (value <= ((MAX_INT - 9) / 10))) {
        return (value * 10) + digit;
    }
    

    您可以使用std::numeric_limits&lt;typeof(value)&gt;::max() 或类似名称代替 MAX_INT,以支持除 int 以外的类型。

    【讨论】:

      【解决方案3】:
      断言(数字 >= 0 && 数字

      【讨论】:

        【解决方案4】:

        这是一种比被接受为也很快的答案的更好、更防弹的实现:

        #include <climits>
        #include <cassert>
        
        unsigned int add_digit(unsigned int val, unsigned int digit)
        {
           // These should be computed at compile time and never even be given a memory location
           static const unsigned int max_no_overflow = (UINT_MAX - 9) / 10U;
           static const unsigned int max_maybe_overflow = UINT_MAX / 10U;
           static const unsigned int last_digit = UINT_MAX % 10;
        
           assert(digit >= 0 && digit < 10);
           if ((val > max_no_overflow) && ((val > max_maybe_overflow) || (digit > last_digit))) {
              // handle overflow
           } else {
              return val * 10 + digit;
           }
           assert(false);
        }
        

        您还应该能够将其变成内联函数。溢出检查几乎总是在第一次比较后短路。 &amp;&amp; 之后的子句很简单,您可以(在 32 位二进制补码整数的情况下)将 5 添加到 429496729 的末尾,而不是 6。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-20
          • 1970-01-01
          • 2020-11-18
          • 1970-01-01
          • 2014-06-20
          • 2011-10-02
          相关资源
          最近更新 更多