在C#中处理整数反转并检查溢出。

huangapple go评论81阅读模式
英文:

Handling Integer Reversal with Overflow Check in C#

问题

我正在努力编写一个在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的绝对值会导致溢出。

有人能否建议如何处理负数的反转,同时避免溢出?

英文:

I am working on a function to reverse an integer in C# while also handling negative numbers. I have come up with the following implementation:

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

        bool isNegative = false;
        if (x &lt; 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 &gt; INT_MAX || reversed &lt; INT_MIN)
        {
            Console.WriteLine(0);
        }

        Console.WriteLine ((int)reversed);
    }

The function seems to work fine for positive numbers, but when I pass in INT_MIN, which is -2147483648, I encounter unexpected behavior. The Math.Abs(x) call throws a System.OverflowException: Negating the minimum value of a two's complement number is invalid.

My intention was to convert the input integer to its absolute value before reversing it, so the function can correctly handle negative numbers. However, it seems that taking the absolute value of INT_MIN is causing an overflow in this implementation.

Can someone please suggest how I can handle the reversal of negative numbers while also avoiding overflow?

答案1

得分: 1

以下是翻译好的部分:

  1. The modulus operator % works just fine on negative numbers and returns a negative result. So the range of possible outputs from x % 10 is [-9..9]. For what you're trying to do this means that you don't have to explicitly handle negative numbers, you can just ignore them.

    模数运算符“%”在负数上也可以正常工作,并返回一个负的结果。因此,“x % 10”的可能输出范围是“[-9..9]”。对于你尝试做的事情,这意味着你不必显式处理负数,可以只是忽略它们。

  2. This simplifies the method significantly:

    这显著简化了方法:

  3. For int.MinValue (your INT_MIN) the sequence goes like this:

    对于int.MinValue(你的INT_MIN),序列如下:

  4. Since I like nice compact code, let's use a for loop to cut down the lines:

    由于我喜欢简洁的代码,让我们使用一个“for”循环来减少行数:

  5. (Yes, I could have put the body in the loop increment too, but this is easier to read.)

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

英文:

There are a couple of things you can do: use a long for your intermediate value or ignore negatives.

The modulus operator % works just fine on negative numbers and returns a negative result. So the range of possible outputs from x % 10 is [-9..9]. For what you're trying to do this means that you don't have to explicitly handle negative numbers, you can just ignore them.

This simplifies the method significantly:

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

For int.MinValue (your INT_MIN) the sequence goes like this:

x x % 10 result
-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

Since I like nice compact code, let's use a for loop to cut down the lines:

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

(Yes, I could have put the body in the loop increment too, but this is easier to read.)

huangapple
  • 本文由 发表于 2023年8月4日 07:06:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76832076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定