정수
일반적으로 우리는 부동 소수점 연산, 반올림 오류 등을 사용하지 않기 때문에 복식을 사용하고 싶지 않습니다. 그것들은 필요하지 않습니다.
이를 위해 상한 나눗셈을 수행하는 방법을 기억하는 것이 좋습니다. 복수 ceil(x / y)
는 (x + y - 1) / y
(음수를 피하면서 오버플로를 조심하면서) 쓸 수 있습니다 .
읽을 수있는
가독성을 원한다면 물론 다음과 같이 프로그래밍 할 수도 있습니다 (예 : Java의 경우 C의 경우 매크로를 사용할 수 있음).
public static int ceilDiv(int x, int y) {
return (x + y - 1) / y;
}
public static int paddedBase64(int n) {
int blocks = ceilDiv(n, 3);
return blocks * 4;
}
public static int unpaddedBase64(int n) {
int bits = 8 * n;
return ceilDiv(bits, 6);
}
// test only
public static void main(String[] args) {
for (int n = 0; n < 21; n++) {
System.out.println("Base 64 padded: " + paddedBase64(n));
System.out.println("Base 64 unpadded: " + unpaddedBase64(n));
}
}
인라인
패딩
우리는 각 3 바이트 (또는 그 이하)마다 4 문자 블록이 필요하다는 것을 알고 있습니다. 따라서 공식은 (x = n 및 y = 3)이됩니다.
blocks = (bytes + 3 - 1) / 3
chars = blocks * 4
또는 결합 :
chars = ((bytes + 3 - 1) / 3) * 4
컴파일러는를 최적화 3 - 1
하므로 가독성을 유지하려면 그대로 두십시오.
패딩되지 않은
패딩되지 않은 변형은 덜 일반적입니다.이를 위해 각 6 비트마다 문자가 필요하다는 것을 기억합니다.
bits = bytes * 8
chars = (bits + 6 - 1) / 6
또는 결합 :
chars = (bytes * 8 + 6 - 1) / 6
그러나 여전히 원하는 경우 두 개로 나눌 수 있습니다.
chars = (bytes * 4 + 3 - 1) / 3
읽을 수 없음
컴파일러가 자신을 위해 최종 최적화를 수행한다고 신뢰하지 않는 경우 (또는 동료를 혼동시키려는 경우) :
패딩
((n + 2) / 3) << 2
패딩되지 않은
((n << 2) | 2) / 3
따라서 우리는 두 가지 논리적 계산 방법이 있으며, 실제로 원하지 않는 한 분기, 비트 연산 또는 모듈로 연산이 필요하지 않습니다.
노트:
- 분명히 널 종료 바이트를 포함하기 위해 계산에 1을 추가해야 할 수도 있습니다.
- Mime의 경우 가능한 줄 종결 문자 등을 관리해야 할 수도 있습니다 (다른 답변 찾기).