티스토리 뷰
leetcode.com/problems/string-to-integer-atoi
위 알고리즘 문제를 풀다가 스위프트 오버플로우 연산에 대해 궁금해졌습니다.
범위 넘어가는 작업을 처리하다가 스위프트에 오버플로우 연산에 대해 궁금해졌고 공부하고 정리해야겠다 생각이 들었습니다.
*문제에서 제약 조건
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. If the numerical value is out of the range of representable values, INT_MAX (231 − 1) or INT_MIN (−231) is returned.
32 비트 부호 있는 정부 범위 내에서만 정수를 저장할 수 있는 환경을 다루고 있다고 가정합니다. 숫자 값은 -2^31 에서 2^31-1 사이고 표현 가능한 값의 범위를 벗어나면 INT_MAX(2^31-1) 또는 INT_MIN (-2^31)이 반환되어야 합니다.
일단 저는 스위프트 오버플로우 연산이 있다는 것은 알았지만 한 번도 사용한 적이 없었어요.
(자랑)
오버플로우 연산자
스위프트에서 정수 상수 또는 변수에 가질 수 없는 값을 숫자를 삽입하려고 하면 기본적으로 오류를 냅니다.
이 오버플로우 연산자는 너무 크거나 너무 작은 숫자로 작업할 때(가질 수 있는 값의 경계에 있을 때)
추가적으로 안전하게 할 수 있도록 해줍니다.
예를 들어 Int16 정수는 -32768과 32767사이에 값을 가질 수 있습니다.
Int16 상수 또는 변수는 범위 밖의 숫자의 값이 들어오게 되면 오류가 발생합니다.
var potentialOverflow = Int16.max
// potentialOverflow equals 32767, which is the maximum value an Int16 can hold
potentialOverflow += 1
// this causes an error
값이 너무 크거나 작을 때 대해서 오류 처리를 제공하면 가질 수 있는 값의 경계에 있는 조건을 코딩할 때 훨씬 더 많은 유연성을 제공할 수 있습니다.
즉 오류를 트리거하는 대신에 가능한 비트 수를 자르고 싶은 경우는 오버 플로우 연산자를 사용하면 됩니다.
이는 모두 &로 시작합니다.
&+ 더하기 오버플로우
&- 빼기 오버플로우
&* 곱하기 오버플로우
값 오버플로우
숫자는 양의 방향과 음의 방향으로 오버플로우 될 수 있습니다.
더하기 오버플로우 연산자(&+)를 사용해 부호없는 정수가 양의 방향으로 오버플로우 되는 예제를 살펴봅시다.
var unsignedOverflow = UInt8.max
// unsignedOverflow equals 255, which is the maximum value a UInt8 can hold
unsignedOverflow = unsignedOverflow &+ 1
// unsignedOverflow is now equal to 0
변수 unsignedOverflow는 Uint8은 보유할 수 있는 최댓값으로 초기화가 됩니다. (255, 이진수로는 11111111)
다음 오버플로우 더하기 연산자(&+)를 사용해 1 증가합니다.
아래 이미지 다이어그램에 표시된 것처럼 UInt8이 가질 수 있는 크기보다 커 가능 범위를 넘어 오버플로우 됩니다.
더하기 오버플로우 연산을 통해 더해진 후 UInt8에 남아있는 값은 0 이진수로는 00000000입니다.
부호 없는 정수가 음의 방향으로 오버플로우 될 때도 비슷한 상황이 발생합니다.
다음은 빼기 오버플로우 연산자(&-)가 사용되는 예입니다.
var unsignedOverflow = UInt8.min
// unsignedOverflow equals 0, which is the minimum value a UInt8 can hold
unsignedOverflow = unsignedOverflow &- 1
// unsignedOverflow is now equal to 255
변수 unsignedOverflow는 Uint8은 보유할 수 있는 최솟값으로 초기화가 됩니다. (0, 이진수로는 00000000)
다음 오버플로우 빼기 연산자(&-)를 사용해 1 감소합니다.
아래 이미지 다이어그램 과 같이 숫자가 넘쳐서 11111111 또는 255로 바뀝니다.
부호 있는 정수에 대해서도 오버플로우가 발생합니다.
부호 있는 정수에 대한 모든 더하기 및 빼기는 비트 bitwise fashion로 수행되며
부호 비트는 비트 왼쪽 및 오른쪽 시프트 연산자와 같이 숫자의 일부로 포함됩니다.
var signedOverflow = Int8.min
// signedOverflow equals -128, which is the minimum value an Int8 can hold
signedOverflow = signedOverflow &- 1
// signedOverflow is now equal to 127
Int8이 보유할 수 있는 최소값은 -128 또는 이진수로는 10000000입니다.
빼기 오버플로우 연산자(&-)를 통해 1빼면 01111111이 되며
이는 부호비트를 토글 하고 UInt8이 보유할 수 있는 최대 양수 값 127을 나타냅니다.
결론은 부호있는 정수와 부호 없는 정수 모두
양수 방향의 오버플로우에서는 최대값에서 최솟값으로 돌아가고
음의 방향 오버플로우에서는 최솟값에서 최댓값으로 돌아갑니다.
docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html
'Tech > Swift' 카테고리의 다른 글
스위프트 mutating 키워드 (0) | 2020.11.12 |
---|---|
스위프트 배열 크기 (0) | 2020.11.09 |
스위프트 비트 연산자 (0) | 2020.09.18 |
dropFirst(_:), removeFirst(_:) 살펴보기 (1) | 2020.09.16 |
스위프트 Identifiable 프로토콜 (0) | 2020.06.16 |
- Total
- Today
- Yesterday
- 딥러닝
- swiftUI
- Xcode
- 스위프트
- objc
- 스위프트UI
- ReactiveX
- rxswift
- RX
- Animation
- 애니메이션
- 책 추천
- SWIFT
- 책
- Algorithm
- iOS SwiftUI
- swift5
- 독서
- objective-c
- stanford SwiftUI
- Deep learning
- wwdc
- leetcode
- string
- 머신러닝
- ARC
- 문자열
- ios
- 책 후기
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |