Integer
Umumnya kami tidak ingin menggunakan ganda karena kami tidak ingin menggunakan operasi floating point, pembulatan kesalahan, dll. Mereka tidak perlu.
Untuk ini adalah ide yang baik untuk mengingat bagaimana melakukan pembagian plafon: ceil(x / y)
dalam ganda dapat ditulis sebagai (x + y - 1) / y
(sambil menghindari angka negatif, tetapi waspadalah terhadap melimpah).
Dapat dibaca
Jika Anda menggunakan keterbacaan, tentu saja Anda juga dapat memprogramnya seperti ini (misalnya dalam Java, untuk C Anda dapat menggunakan makro, tentu saja):
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));
}
}
Sebaris
Empuk
Kita tahu bahwa kita membutuhkan 4 blok karakter pada saat itu untuk masing-masing 3 byte (atau kurang). Jadi rumusnya menjadi (untuk x = n dan y = 3):
blocks = (bytes + 3 - 1) / 3
chars = blocks * 4
atau digabungkan:
chars = ((bytes + 3 - 1) / 3) * 4
kompiler Anda akan mengoptimalkan 3 - 1
, jadi biarkan saja seperti ini untuk menjaga keterbacaan.
Belum dicetak
Yang kurang umum adalah varian tidak murni, untuk ini kita ingat bahwa setiap kita memerlukan karakter untuk setiap 6 bit, dibulatkan ke atas:
bits = bytes * 8
chars = (bits + 6 - 1) / 6
atau digabungkan:
chars = (bytes * 8 + 6 - 1) / 6
namun kita masih dapat membaginya menjadi dua (jika kita mau):
chars = (bytes * 4 + 3 - 1) / 3
Tidak dapat dibaca
Jika Anda tidak percaya kompiler Anda untuk melakukan optimasi akhir untuk Anda (atau jika Anda ingin membingungkan kolega Anda):
Empuk
((n + 2) / 3) << 2
Belum dicetak
((n << 2) | 2) / 3
Jadi di sinilah kita, dua cara perhitungan logis, dan kita tidak memerlukan cabang, bit-ops atau modulo ops - kecuali kita benar-benar menginginkannya.
Catatan:
- Jelas Anda mungkin perlu menambahkan 1 ke perhitungan untuk memasukkan byte terminasi nol.
- Untuk Mime Anda mungkin perlu mengurus kemungkinan karakter pemutusan baris dan semacamnya (cari jawaban lain untuk itu).