_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
_の範囲内ではないですか?私には何が欠けていますか?
コメントで述べたように、最初の逆で確認する必要があります。ただし、これは別のチェック方法です。
確認するには、&
適切なマスクを使用した結果。
したがって、あなたの場合、制限は−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
と説明されたロジックに従ってそれらをチェックします。
解決策はすでにあります。これは私のような初心者に役立つので、私はこれを投稿しています。私は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
これは、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
制限に追加の変数を使用せずに結果のオーバーフローをチェックする別の方法は次のとおりです。
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
シンプルで純粋な数学-
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)