Số nguyên
Nói chung, chúng tôi không muốn sử dụng gấp đôi vì chúng tôi không muốn sử dụng ops dấu phẩy động, lỗi làm tròn, v.v ... Chúng không cần thiết.
Đối với điều này, bạn nên nhớ cách thực hiện phép chia trần: ceil(x / y)
trong hai lần có thể được viết là (x + y - 1) / y
(trong khi tránh các số âm, nhưng hãy cẩn thận khi tràn).
Có thể đọc được
Nếu bạn muốn đọc, tất nhiên bạn cũng có thể lập trình như thế này (ví dụ trong Java, đối với C, bạn có thể sử dụng macro, tất nhiên):
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));
}
}
Nội tuyến
Đệm
Chúng tôi biết rằng chúng tôi cần 4 khối ký tự tại mỗi thời điểm cho mỗi 3 byte (hoặc ít hơn). Vì vậy, công thức trở thành (cho x = n và y = 3):
blocks = (bytes + 3 - 1) / 3
chars = blocks * 4
hoặc kết hợp:
chars = ((bytes + 3 - 1) / 3) * 4
trình biên dịch của bạn sẽ tối ưu hóa 3 - 1
, vì vậy hãy để nó như thế này để duy trì khả năng đọc.
Không đệm
Ít phổ biến hơn là biến thể không được đệm, vì điều này chúng ta nhớ rằng mỗi chúng ta cần một ký tự cho mỗi 6 bit, được làm tròn lên:
bits = bytes * 8
chars = (bits + 6 - 1) / 6
hoặc kết hợp:
chars = (bytes * 8 + 6 - 1) / 6
tuy nhiên chúng ta vẫn có thể chia cho hai (nếu chúng ta muốn):
chars = (bytes * 4 + 3 - 1) / 3
Không thể đọc được
Trong trường hợp bạn không tin tưởng trình biên dịch của mình thực hiện các tối ưu hóa cuối cùng cho bạn (hoặc nếu bạn muốn gây nhầm lẫn cho đồng nghiệp của mình):
Đệm
((n + 2) / 3) << 2
Không đệm
((n << 2) | 2) / 3
Vì vậy, chúng tôi có hai cách tính toán hợp lý và chúng tôi không cần bất kỳ nhánh, bit-op hoặc modulo ops - trừ khi chúng tôi thực sự muốn.
Ghi chú:
- Rõ ràng bạn có thể cần thêm 1 vào các tính toán để bao gồm một byte kết thúc null.
- Đối với Mime, bạn có thể cần phải quan tâm đến các ký tự kết thúc dòng có thể và như vậy (tìm kiếm các câu trả lời khác cho điều đó).