web-dev-qa-db-ja.com

32ビット整数を反転

_signed 32bit integers_を扱う leetcode.com の問題を解決しようとしています。

タスクは次のとおりです。

符号付き32ビット整数の逆数を返し、32ビット符号付き整数の範囲をオーバーフローする場合は0を返します。

ウィキペディア

32ビットのレジスタは、32の異なる値を格納できます。 32ビットに格納できる整数値の範囲は、使用される整数表現によって異なります。最も一般的な2つの表現では、範囲は(符号なし)2進数としての表現の場合は0から4,294,967,295(2 ^ 32 − 1)、表現の場合は-2,147,483,648(−2 ^ 31)から2,147,483,647(2 ^ 31 − 1)です。 2の補数として。

したがって、私が理解したことが正しい場合は、0 to (2^31)-1と_(-2^31) to 0_の間でテストする必要があります。それ以外の場合は、_0_を返します。

これが私のコードです:

_def reverse_int(nums):
    a = str(nums)

    if 0 < nums <= (1 << 31)-1:
        return int(a[::-1])

    Elif (-1 << 31) <= nums < 0:
        return -(int(a[:-len(a):-1]))
    else:
        return 0
_

これが私の問題です:私がウェブサイトで私のコードをテストすると:

_nums = 1534236469 # Fail
nums = 1463847412 # Success
nums = 9000000    # Success
_

現在のコードが_1534236469_で失敗するのはなぜですか? _1534236469_は_32 bit signed integers_の範囲内ではないですか?私には何が欠けていますか?

7
Chiheb Nexus

コメントで述べたように、最初の逆で確認する必要があります。ただし、これは別のチェック方法です。

確認するには、&適切なマスクを使用した結果。

したがって、あなたの場合、制限は−2,147,483,648および2,147,483,647それらの16進値は-0x80000000および0x7fffffff

インタプリタでこれを試してください。

>>> 0x7fffffff
2147483647
>>> 2147483647 & 0x7fffffff   #within limit
2147483647

制限を超える値は、他の値が表示されていることがわかります。

>>> 2147483648 & 0x7fffffff     #Exceeds limit
0
>>> 98989898989898 & 0x7fffffff  #Exceeds limit
1640235338

ただし、値が制限内の場合。値は出力として与えられます。

>>> 1 & 0x7fffffff               #within limit
1
>>> 780 & 0x7fffffff
780

負の値の場合

 >>> -0x80000000     #Limit
-2147483648
>>> -2147483648 & -0x80000000
-2147483648

値が範囲内の場合。 limitが出力として表示されます。

>>> -2147483647 & -0x80000000
-2147483648
>>> -2 & -0x80000000          #within limit
-2147483648
>>> -2323 & -0x80000000
-2147483648

ただし、値が範囲外の場合は、他の値が表示されることがあります。

>>> -2147483649 & -0x80000000
-4294967296
>>> -999999999999 & -0x80000000
-1000727379968

あなたはこれをうまく利用して、あなたが望むものを手に入れることができます!

ここにあなたがしたいことをするプログラムがあります。

def reverse(x):
    str_x = str(x)
    if x<0:
        str_x = '-'+str_x[::-1][:-1]
        x = int(str_x)
    else:
        str_x = str_x[::-1]
        x = int(str_x)
    neg_limit= -0x80000000
    pos_limit= 0x7fffffff

    if(x<0):
        val=x&neg_limit
        if(val==neg_limit):
            return x
        else:
            return 0
    Elif(x==0):
        return x
    else:
        val = x&pos_limit
        if(val==x):
            return x
        else:
            return 0

value = int(input("Enter value: "))
print(reverse(value))

以下の部分は、負の値と正の値の両方について逆になっています。

if x<0:
    str_x = '-'+str_x[::-1][:-1]
    x = int(str_x)
    print(x)
else:
    str_x = str_x[::-1]
    x = int(str_x)
    print(x)

制限を設定するneg_limit= -0x80000000およびpos_limit= 0x7fffffffと説明されたロジックに従ってそれらをチェックします。

18
void

解決策はすでにあります。これは私のような初心者に役立つので、私はこれを投稿しています。私はvoid'sソリューション(上記)を使用してそれを完成させました。最初は、逆の方法を実行せずにテストを行いましたが、元の質問で述べたような問題がありました。次に、正と負の両方で数値を逆にしてからテストを行いましたが、うまくいきました。

def reverse(self, x: int) -> int:
        neg_limit =-0x80000000 # hex(-2**31-1),see details in accepted answer above
        pos_limit = 0x7fffffff #hex(2**31-1)
        if x >0:
            reverse_num = int(str(x)[::-1])
            if reverse_num & pos_limit==reverse_num: #conditions explained above
                return reverse_num
            else:
                return 0

        Elif x <0:
            reverse_num = -int(str(abs(x))[::-1])
            if reverse_num&neg_limit == neg_limit:
                return reverse_num
            else:
                    return 0
        else:
            return 0
2
hemanta

これは、nums = 1534236469が32ビットの符号付き整数の範囲内にあるために発生しますが、逆に9646324351は32ビットの符号付き整数の範囲内にありません。

class Solution:
def reverse(self, x: int) -> int:
    if x in range((-1 << 31),(1 << 31)-1):
        r=0
        c=False
        if(x<0):
            c=True
            x*=-1

        while(x!=0):
            r=10*r+x%10
            x=x//10
        if(c):
            r*=-1
        if r in range((-1 << 31),(1 << 31)-1):
            return r
        else:
            return 0
    else:
        return 0
0
Vikash Kumar

制限に追加の変数を使用せずに結果のオーバーフローをチェックする別の方法は次のとおりです。

def reverse(x):
    num = str(abs(x))

    if x < 0:
        result = -1 * int(num[::-1])
    else:
        result = int(num[::-1])

    if result not in range((-1 << 31), (1 << 31) - 1):
        return 0

    return result
0
Laur

シンプルで純粋な数学-

def reverse(self, x: int) -> int:
        r = 2 ** 31
        maxLimit = r - 1
        minLimit = r * -1
        rev = None
        negative = False

        if x < 0:
            negative = True
            x = x * -1

        while True:
            mod = x % 10
            x = (x - mod) / 10

            if not rev:
                rev = mod
            else:
                rev = (rev * 10) + mod

            if x <= 0:
                break

        if negative:
            rev = rev * -1

        returnValue = int(rev)
        if returnValue < minLimit or returnValue > maxLimit:
            return 0 #Return whatever you want. if overflows
        return int(rev)
0
Keshari Nandan