(a + b) / 2
더해서 2로 나누는 것은 오버플로우가 발생한다.
int a = 1_894_234_753;
int b = 1_882_312_653;
System.out.println((a+b)/2); // -259209945
low + (high - low) / 2
둘중에 큰 수를 알면 두 값의 차이를 작은 수에 더해서 2로 나누는 것도 가능하다.
int low = 1_894_234_753;
int high = 1_882_312_653;
System.out.println(low + (high-low)/2); // 1888273703
(a / 2) + (b / 2) + (a & b & 1)
어떤게 큰 수인지 몰라도 가능한 알고리듬은 2016년에 특허가 만료되었다.
- 홀수 + 홀수일 경우 1이 생략되기 때문에둘 다 홀수일 경우 1이 찍히는 a&b&1을 더해준다.
int a = 1_894_234_753;
int b = 1_882_312_653
// 홀수 + 홀수일 경우 1이 생략됨
// a&b&1 -> 둘 다 홀수일 경우 1
System.out.println(a/2+b/2 + a&b&1); // 1888273703
(a & b) + (a ^ b) / 2
SWAR : SIMD within a register
13: 1101
14: 1110
a&b + a^b = 1100 + 0011 = 1111 = 14
a&b + a^b/2 = 1100 + 0001 = 1101 = 13
14 : 1110
12 : 1100
a&b + a^b 1100+0010 = 1110 = 14
a&b + a^b/2 = 1100+0001 = 1101 = 13
int a = 1_894_234_753;
int b = 1_882_312_653;
System.out.println((a&b) + (a^b)/2); // 1888273703
((long)a + b) / 2
컴파일러가 64비트를 지원한다면 캐스팅. 이게 젤 편하긴 하다.
int a = 1_894_234_753;
int b = 1_882_312_653;
System.out.println(((long)a+b)/2); // 1888273703
ArrayList capacity 증가하는 방식
Java 6
(oldCapacity * 3) / 2 + 1 -> *3 에서 overflow가 발생한다.
Java 7 이후
oldCapacity + (oldCapacity >> 1)로 변경
참고
On finding the average of two unsigned integers without overflow
'Dot Programming > Java' 카테고리의 다른 글
JVM 1 - Java Architecture, JVM Specification (0) | 2022.05.31 |
---|---|
[Play with Java] Java 8로 꼬리재귀 함수 만들기 (Tail Recursion) (3) | 2022.04.10 |
[Java] 자바 서블릿과 서블릿 컨테이너 2 - MVC 패턴 도입 (0) | 2022.02.10 |
[Java] 자바 서블릿과 서블릿 컨테이너 1 - 웹 서버 한계와 WAS 등장 (0) | 2022.02.10 |
[Java] 자바8에 도입된 인터페이스의 디폴트 메서드 (Default Method) (0) | 2022.02.02 |