nanoprintf adalah implementasi snprintf dan vsnprintf yang tidak terbebani untuk sistem tertanam yang, jika diaktifkan sepenuhnya, bertujuan untuk memenuhi standar C11. Pengecualian utama adalah floating-point, notasi ilmiah ( %e
, %g
, %a
), dan konversi yang memerlukan keberadaan wcrtomb
. Output bilangan bulat biner C23 secara opsional didukung sesuai N2630. Ekstensi keamanan untuk snprintf dan vsnprintf dapat dikonfigurasi secara opsional untuk mengembalikan string yang terpotong atau kosong sepenuhnya pada peristiwa buffer overflow.
Selain itu, nanoprintf dapat digunakan untuk mengurai string format gaya printf untuk mengekstrak berbagai parameter dan penentu konversi, tanpa melakukan pemformatan teks sebenarnya.
nanoprintf tidak membuat alokasi memori dan menggunakan tumpukan kurang dari 100 byte. Ini mengkompilasi antara ~740-2640 byte kode objek pada arsitektur Cortex-M0, tergantung pada konfigurasi.
Semua kode ditulis dalam dialek minimal C99 untuk kompatibilitas kompiler maksimal, dikompilasi dengan rapi pada tingkat peringatan tertinggi di clang + gcc + msvc, tidak menimbulkan masalah dari UBsan atau Asan, dan diuji secara mendalam pada arsitektur 32-bit dan 64-bit . nanoprintf menyertakan header standar C tetapi hanya menggunakannya untuk tipe C99 dan daftar argumen; tidak ada panggilan yang dilakukan ke stdlib/libc, dengan pengecualian panggilan aritmatika integer besar internal yang mungkin dikeluarkan oleh kompiler Anda. Seperti biasa, beberapa header khusus Windows diperlukan jika Anda mengkompilasi secara asli untuk msvc.
nanoprintf adalah file header tunggal dengan gaya perpustakaan stb. Repositori lainnya adalah pengujian dan perancah dan tidak diperlukan untuk digunakan.
nanoprintf dapat dikonfigurasi secara statis sehingga pengguna dapat menemukan keseimbangan antara ukuran, persyaratan kompiler, dan rangkaian fitur. Konversi floating-point, pengubah panjang "besar", dan penulisan kembali ukuran semuanya dapat dikonfigurasi dan hanya dikompilasi jika diminta secara eksplisit, lihat Konfigurasi untuk detailnya.
Tambahkan kode berikut ke salah satu file sumber Anda untuk mengkompilasi implementasi nanoprintf:
// define your nanoprintf configuration macros here (see "Configuration" below) #define NANOPRINTF_IMPLEMENTATION #include "path/to/nanoprintf.h"
Kemudian, di file mana pun yang ingin Anda gunakan nanoprintf, cukup sertakan header dan panggil fungsi npf_:
#include "nanoprintf.h" void print_to_uart(void) { npf_pprintf(&my_uart_putc, NULL, "Hello %s%c %d %u %fn", "worl", 'd', 1, 2, 3.f); } void print_to_buf(void *buf, unsigned len) { npf_snprintf(buf, len, "Hello %s", "world"); }
Lihat contoh "Gunakan nanoprintf secara langsung" dan "Bungkus nanoprintf" untuk detail selengkapnya.
Saya menginginkan printf drop-in domain publik satu file yang berukuran di bawah 1KB dalam konfigurasi minimal (bootloader dll), dan di bawah 3KB dengan lonceng dan peluit floating-point diaktifkan.
Dalam pekerjaan firmware, saya biasanya ingin pemformatan string stdio tanpa persyaratan lapisan syscall atau deskriptor file; mereka hampir tidak pernah diperlukan dalam sistem kecil di mana Anda ingin masuk ke buffer kecil atau memancarkan langsung ke bus. Selain itu, banyak implementasi stdio yang tertanam berukuran lebih besar atau lebih lambat dari yang seharusnya - ini penting untuk pekerjaan bootloader. Jika Anda tidak memerlukan syscalls atau stdio bells + whistles, Anda cukup menggunakan nanoprintf dan nosys.specs
dan memperkecil build Anda.
Kode ini dioptimalkan untuk ukuran, bukan keterbacaan atau struktur. Sayangnya modularitas dan "kebersihan" (apa pun artinya) menambah overhead pada skala kecil ini, sehingga sebagian besar fungsi dan logika digabungkan menjadi npf_vpprintf
. Ini bukanlah tampilan kode sistem tertanam yang normal; ini sup #ifdef
dan sulit dipahami, dan saya minta maaf jika Anda harus ragu-ragu dalam penerapannya. Mudah-mudahan berbagai tes ini bisa menjadi panduan jika Anda meretasnya.
Sebagai alternatif, mungkin Anda adalah programmer yang jauh lebih baik daripada saya! Dalam hal ini, tolong bantu saya membuat kode ini lebih kecil dan bersih tanpa membuat jejaknya lebih besar, atau dorong saya ke arah yang benar. :)
nanoprintf memiliki 4 fungsi utama:
npf_snprintf
: Gunakan seperti snprintf.
npf_vsnprintf
: Gunakan seperti vsnprintf (dukungan va_list
).
npf_pprintf
: Gunakan seperti printf dengan panggilan balik tulis per karakter (semihosting, UART, dll).
npf_vpprintf
: Gunakan seperti npf_pprintf
tetapi membutuhkan va_list
.
Variasi pprintf
mengambil panggilan balik yang menerima karakter untuk dicetak dan penunjuk konteks yang disediakan pengguna.
Berikan NULL
atau nullptr
ke npf_[v]snprintf
untuk tidak menulis apa pun, dan hanya mengembalikan panjang string yang diformat.
nanoprintf tidak menyediakan printf
atau putchar
itu sendiri; itu dilihat sebagai layanan tingkat sistem dan nanoprintf adalah perpustakaan utilitas. nanoprintf mudah-mudahan merupakan blok bangunan yang baik untuk menggulirkan printf
Anda sendiri.
Semua fungsi nanoprintf mengembalikan nilai yang sama: jumlah karakter yang dikirim ke callback (untuk npf_pprintf) atau jumlah karakter yang akan ditulis ke buffer asalkan ada ruang yang cukup. Terminator nol 0 byte bukan bagian dari penghitungan.
Standar C memungkinkan fungsi printf mengembalikan nilai negatif jika pengkodean string atau karakter tidak dapat dilakukan, atau jika aliran keluaran menemui EOF. Karena nanoprintf tidak menyadari sumber daya OS seperti file, dan tidak mendukung pengubah panjang l
untuk dukungan wchar_t
, kesalahan runtime apa pun bisa berupa bug internal (harap laporkan!) atau penggunaan yang salah. Oleh karena itu, nanoprintf hanya mengembalikan nilai non-negatif yang mewakili berapa banyak byte yang terdapat dalam string yang diformat (sekali lagi, dikurangi byte terminator nol).
nanoprintf memiliki flag konfigurasi statis berikut.
NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan penentu lebar bidang.
NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan penentu presisi.
NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan penentu floating-point.
NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan pengubah berukuran besar.
NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan penentu biner.
NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS
: Setel ke 0
atau 1
. Mengaktifkan %n
untuk menulis kembali.
NANOPRINTF_VISIBILITY_STATIC
: Definisi opsional. Menandai prototipe sebagai static
pada sandbox nanoprintf.
Jika tidak ada tanda konfigurasi yang ditentukan, nanoprintf akan menetapkan nilai bawaan yang "wajar" sebagai upaya untuk membantu: float diaktifkan, tetapi writeback, biner, dan pemformat besar dinonaktifkan. Jika ada flag konfigurasi yang ditentukan secara eksplisit, nanoprintf mengharuskan semua flag ditentukan secara eksplisit.
Jika fitur penentu format yang dinonaktifkan digunakan, tidak ada konversi yang akan terjadi dan string penentu format hanya akan dicetak.
nanoprintf memiliki definisi konfigurasi khusus floating-point berikut.
NANOPRINTF_CONVERSION_BUFFER_SIZE
: Opsional, defaultnya adalah 23
. Menetapkan ukuran buffer karakter yang digunakan untuk menyimpan nilai yang dikonversi. Atur ke angka yang lebih besar untuk mengaktifkan pencetakan angka floating-point dengan lebih banyak karakter. Ukuran buffer mencakup bagian bilangan bulat, bagian pecahan, dan pemisah desimal, tetapi tidak menyertakan tanda dan karakter pengisi. Jika nomor tersebut tidak masuk ke dalam buffer, err
akan dicetak. Hati-hati dengan ukuran besar karena buffer konversi dialokasikan pada memori tumpukan.
NANOPRINTF_CONVERSION_FLOAT_TYPE
: Opsional, defaultnya adalah unsigned int
. Menetapkan tipe integer yang digunakan untuk algoritma konversi float, yang menentukan akurasi konversi. Dapat disetel ke tipe bilangan bulat apa pun yang tidak ditandatangani, seperti misalnya uint64_t
atau uint8_t
.
Secara default, npf_snprintf dan npf_vsnprintf berperilaku sesuai dengan Standar C: buffer yang disediakan akan terisi tetapi tidak dibanjiri. Jika string melebihi buffer, byte terminator nol akan ditulis ke byte terakhir buffer. Jika buffer berukuran null
atau nol, tidak ada byte yang akan ditulis.
Jika Anda mendefinisikan NANOPRINTF_SNPRINTF_SAFE_EMPTY_STRING_ON_OVERFLOW
dan string Anda lebih besar dari buffer Anda, byte pertama buffer akan ditimpa dengan byte terminator nol. Semangatnya mirip dengan snprintf_s Microsoft.
Dalam semua kasus, nanoprintf akan mengembalikan jumlah byte yang akan ditulis ke buffer, jika terdapat cukup ruang. Nilai ini tidak memperhitungkan byte terminator nol, sesuai dengan Standar C.
nanoprintf hanya menggunakan memori tumpukan dan tidak ada primitif konkurensi, sehingga secara internal ia tidak menyadari lingkungan eksekusinya. Hal ini membuatnya aman untuk memanggil dari beberapa konteks eksekusi secara bersamaan, atau untuk menginterupsi panggilan npf_
dengan panggilan npf_
lainnya (misalnya, ISR atau semacamnya). Jika Anda menggunakan npf_pprintf
secara bersamaan dengan target npf_putc
yang sama, Anda bebas memastikan kebenaran di dalam panggilan balik Anda. Jika Anda npf_snprintf
dari beberapa thread ke buffer yang sama, Anda akan mengalami perlombaan data yang jelas.
Seperti printf
, nanoprintf
mengharapkan string spesifikasi konversi dalam bentuk berikut:
[flags][field width][.precision][length modifier][conversion specifier]
Bendera
Tidak ada atau lebih hal berikut ini:
0
: Isi bidang dengan karakter nol di depannya.
-
: Rata kiri hasil konversi pada kolom.
+
: Konversi bertanda selalu dimulai dengan karakter +
atau -
.
: (spasi) Karakter spasi disisipkan jika karakter pertama yang dikonversi bukan merupakan tanda.
#
: Menulis karakter tambahan ( 0x
untuk hex, .
untuk float kosong, '0' untuk oktal kosong, dll).
Lebar bidang (jika diaktifkan)
Angka yang menentukan total lebar bidang untuk konversi, menambahkan padding. Jika lebar bidang adalah *
, lebar bidang dibaca dari vararg berikutnya.
Presisi (jika diaktifkan)
Diawali dengan .
, angka yang menentukan ketepatan angka atau string. Jika presisi adalah *
, presisi dibaca dari vararg berikutnya.
Pengubah panjang
Tidak ada atau lebih hal berikut ini:
h
: Gunakan short
dari lebar vararg integral dan tulis kembali.
L
: Gunakan long double
untuk lebar float vararg (catatan: kemudian akan diturunkan menjadi double
)
l
: Gunakan lebar vararg long
, double
, atau wide.
hh
: Gunakan char
untuk lebar vararg integral dan tulis kembali.
ll
: (penentu besar) Gunakan long long
untuk lebar vararg integral dan tulis kembali.
j
: (penentu besar) Gunakan tipe [u]intmax_t
untuk lebar vararg integral dan tulis kembali.
z
: (penentu besar) Gunakan tipe size_t
untuk lebar vararg integral dan tulis kembali.
t
: (penentu besar) Gunakan tipe ptrdiff_t
untuk lebar vararg integral dan tulis kembali.
Penentu konversi
Tepatnya salah satu dari berikut ini:
%
: Literal tanda persen
c
: Karakter
s
: String yang diakhiri dengan null
i
/ d
: Bilangan bulat bertanda
u
: Bilangan bulat tak bertanda tangan
o
: Bilangan bulat oktal tak bertanda tangan
x
/ X
: Bilangan bulat heksadesimal tak bertanda
p
: Petunjuk
n
: Tulis jumlah byte yang ditulis ke pointer vararg
f
/ F
: Desimal titik mengambang
e
/ E
: Ilmiah titik-mengambang (tidak diterapkan, mencetak desimal mengambang)
g
/ G
: Titik mengambang terpendek (tidak diterapkan, mencetak desimal mengambang)
a
/ A
: Hex titik-mengambang (tidak diterapkan, mencetak desimal mengambang)
b
/ B
: Bilangan bulat biner
Konversi floating-point dilakukan dengan mengekstraksi bagian bilangan bulat dan pecahan suatu bilangan menjadi dua variabel bilangan bulat terpisah. Untuk setiap bagian, eksponennya kemudian diskalakan dari basis-2 ke basis-10 dengan mengalikan dan membagi mantissa secara berulang dengan 2 dan 5 secara tepat. Urutan operasi penskalaan dipilih secara dinamis (bergantung pada nilainya) untuk mempertahankan sebanyak mungkin bit mantissa yang paling signifikan. Semakin jauh nilainya dari pemisah desimal, semakin besar kesalahan penskalaan yang terakumulasi. Dengan rata-rata lebar jenis bilangan bulat konversi N
bit, algoritme mempertahankan akurasi N - log2(5)
atau N - 2.322
bit. Selain itu bagian bilangan bulat hingga 2 ^^ N - 1
dan bagian pecahan hingga N - 2.322
bit setelah pemisah desimal dikonversi dengan sempurna tanpa kehilangan bit apa pun.
Karena float -> kode tetap beroperasi pada bit nilai float mentah, tidak ada operasi floating-point yang dilakukan. Hal ini memungkinkan nanoprintf untuk memformat float secara efisien pada arsitektur soft-float seperti Cortex-M0, berfungsi secara identik dengan atau tanpa pengoptimalan seperti "matematika cepat", dan untuk meminimalkan jejak kode.
Penentu %e
/ %E
, %a
/ %A
, dan %g
/ %G
diuraikan tetapi tidak diformat. Jika digunakan, outputnya akan sama dengan jika %f
/ %F
digunakan. Permintaan tarik diterima! :)
Tidak ada dukungan karakter luas: bidang %lc
dan %ls
mengharuskan argumen dikonversi ke array char seolah-olah dengan panggilan ke wcrtomb. Ketika konversi lokal dan rangkaian karakter terlibat, sulit untuk mempertahankan nama "nano". Oleh karena itu, %lc
dan %ls
berperilaku seperti %c
dan %s
.
Saat ini satu-satunya konversi float yang didukung adalah bentuk desimal: %f
dan %F
. Permintaan tarik diterima!
Build CI disiapkan untuk menggunakan gcc dan nm guna mengukur ukuran kompilasi setiap permintaan pull. Lihat keluaran pekerjaan "laporan ukuran" Pemeriksaan Prapengiriman untuk proses terkini.
Pengukuran ukuran berikut dilakukan terhadap build Cortex-M0.
Configuration "Minimal": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000270 00000016 T npf_pprintf 000002cc 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000286 00000046 T npf_vsnprintf 00000058 00000218 T npf_vpprintf Total size: 0x2e2 (738) bytes Configuration "Binary": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 000002a8 00000016 T npf_pprintf 00000304 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 000002be 00000046 T npf_vsnprintf 00000058 00000250 T npf_vpprintf Total size: 0x31a (794) bytes Configuration "Field Width + Precision": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 000004fe 00000016 T npf_pprintf 0000055c 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000514 00000048 T npf_vsnprintf 00000058 000004a6 T npf_vpprintf Total size: 0x572 (1394) bytes Configuration "Field Width + Precision + Binary": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000560 00000016 T npf_pprintf 000005bc 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 00000576 00000046 T npf_vsnprintf 00000058 00000508 T npf_vpprintf Total size: 0x5d2 (1490) bytes Configuration "Float": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=0 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=0 - arm-none-eabi-nm --print-size --size-sort npf.o 00000046 00000002 t npf_bufputc_nop 00000048 00000010 t npf_putc_cnt 00000032 00000014 t npf_bufputc 00000618 00000016 T npf_pprintf 00000674 00000016 T npf_snprintf 00000000 00000032 t npf_utoa_rev 0000062e 00000046 T npf_vsnprintf 00000058 000005c0 T npf_vpprintf Total size: 0x68a (1674) bytes Configuration "Everything": arm-none-eabi-gcc -c -x c -Os -I/__w/nanoprintf/nanoprintf -o npf.o -mcpu=cortex-m0 -DNANOPRINTF_IMPLEMENTATION -DNANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS=1 -DNANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS=1 - arm-none-eabi-nm --print-size --size-sort npf.o 0000005a 00000002 t npf_bufputc_nop 0000005c 00000010 t npf_putc_cnt 00000046 00000014 t npf_bufputc 000009da 00000016 T npf_pprintf 00000a38 00000016 T npf_snprintf 00000000 00000046 t npf_utoa_rev 000009f0 00000048 T npf_vsnprintf 0000006c 0000096e T npf_vpprintf Total size: 0xa4e (2638) bytes
Untuk mendapatkan lingkungan dan menjalankan pengujian:
Kloning atau fork repositori ini.
Jalankan ./b
dari root (atau py -3 build.py
dari root, untuk pengguna Windows)
Ini akan membangun semua pengujian unit, kesesuaian, dan kompilasi untuk lingkungan host Anda. Kegagalan pengujian apa pun akan menghasilkan kode keluar yang bukan nol.
Lingkungan pengembangan nanoprintf menggunakan cmake dan ninja. Jika Anda memiliki ini di jalur Anda, ./b
akan menggunakannya. Jika tidak, ./b
akan mengunduh dan menyebarkannya ke path/to/your/nanoprintf/external
.
nanoprintf menggunakan Tindakan GitHub untuk semua pembangunan integrasi berkelanjutan. Build GitHub Linux menggunakan image Docker ini dari repositori Docker saya.
Matriks membangun [Debug, Rilis] x [32-bit, 64-bit] x [Mac, Windows, Linux] x [gcc, clang, msvc], dikurangi konfigurasi clang Mac 32-bit.
Satu rangkaian pengujian adalah cabang dari rangkaian pengujian printf, yang berlisensi MIT. Itu ada sebagai submodul untuk tujuan lisensi- nanoprintf adalah domain publik, jadi rangkaian pengujian khusus ini bersifat opsional dan dikecualikan secara default. Untuk membangunnya, ambil dengan memperbarui submodul dan tambahkan tanda --paland
ke pemanggilan ./b
Anda. Tidak perlu menggunakan nanoprintf sama sekali.
Ide dasar konversi float-to-int terinspirasi oleh algoritma tetap float -> 64:64 Wojciech Muła dan diperluas lebih jauh dengan menambahkan penskalaan dinamis dan lebar integer yang dapat dikonfigurasi oleh Oskars Rubenis.
Saya mem-porting rangkaian pengujian printf ke nanoprintf. Ini awalnya dari basis kode proyek mpaland printf tetapi diadopsi dan ditingkatkan oleh Eyal Rozenberg dan lainnya. (Nanoprintf memiliki banyak pengujiannya sendiri, tetapi pengujian ini juga sangat menyeluruh dan sangat bagus!)
Implementasi biner didasarkan pada persyaratan yang ditentukan oleh proposal N2630 Jörg Wunsch, semoga dapat diterima di C23!