在 C# 中通过溢出检查处理整数反转

问题描述 投票:0回答:1

我正在开发一个在 C# 中反转整数的函数,同时也处理负数。我想出了以下实现:

public void Reverse(int x)
    {
        const int INT_MAX = 2147483647;
        const int INT_MIN = -2147483648;

        bool isNegative = false;
        if (x < 0)
        {
            isNegative = true;
            x = Math.Abs(x);
        }

        long reversed = 0;
        while (x != 0)
        {
            int lastDigit = x % 10;
            reversed = reversed * 10 + lastDigit;
            x = x / 10;
        }

        if (isNegative)
        {
            reversed = -reversed;
        }

        if (reversed > INT_MAX || reversed < INT_MIN)
        {
            Console.WriteLine(0);
        }

        Console.WriteLine ((int)reversed);
    }

该函数对于正数似乎工作得很好,但是当我传入 INT_MIN(即 -2147483648)时,我遇到了意外的行为。 Math.Abs(x) 调用会抛出 System.OverflowException:对二进制补码数的最小值取反是无效的。

我的目的是在反转输入整数之前将其转换为其绝对值,以便该函数可以正确处理负数。然而,在这个实现中,取 INT_MIN 的绝对值似乎会导致溢出。

有人可以建议我如何处理负数的反转,同时避免溢出吗?

c# reverse
1个回答
0
投票

您可以执行以下操作:使用

long
作为中间值或 忽略负值。

模运算符

%
对于负数(在左侧操作数中)工作得很好,并返回负结果。对于你想要做的事情来说,这大大简化了事情。您可以忽略它们,而不是尝试显式处理负数。

这大大简化了方法:

static long Reverse(int x)
{
    long result = 0;
    while (x != 0)
    {
        result = result * 10 + x % 10;
        x /= 10;
    }
    return result;
}

对于

int.MinValue
(你的
INT_MIN
),顺序如下:

x x % 10 结果
-2147483648 -8 -8
-214748364 -4 -84
-21474836 -6 -846
-2147483 -3 -8463
-214748 -8 -84638
-21474 -4 -846384
-2147 -7 -8463847
-214 -4 -84638474
-21 -1 -846384741
-2 -2 -8463847412

因为我喜欢简洁的代码,所以让我们使用

for
循环来减少行数:

static long Reverse(int x)
{
    long result = 0;
    for (; value != 0; value /= 10)
        result = result * 10 + value % 10;
    return result;
}

(是的,我也可以将主体放入循环增量中,但这更容易阅读。)

© www.soinside.com 2019 - 2024. All rights reserved.