#include <stdio.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
Keluaran:
My number is 8 bytes wide and its value is 285212672l. A normal number is 0.
Saya menganggap hasil tak terduga ini dari mencetak unsigned long long int
. Bagaimana Anda printf()
sebuah unsigned long long int
?
Jawaban:
Gunakan pengubah panjang-panjang ll (el-el) dengan konversi u (tidak ditandatangani). (Bekerja di windows, GNU).
sumber
long long
argumen keprintf
dan menggunakan format yang salah untuk salah satu dari mereka, katakan%d
saja%lld
, maka bahkan argumen yang dicetak setelah yang salah dapat sepenuhnya mati (atau bahkan dapat menyebabkanprintf
crash ). Pada dasarnya, argumen variabel diteruskan ke printf tanpa informasi jenis apa pun, jadi jika string format salah, hasilnya tidak dapat diprediksi.Anda mungkin ingin mencoba menggunakan perpustakaan inttypes.h yang memberikan jenis seperti
int32_t
,int64_t
,uint64_t
dll Anda kemudian dapat menggunakan macro nya seperti:Ini "dijamin" untuk tidak memberi Anda masalah yang sama dengan
long
,unsigned long long
dll, karena Anda tidak perlu menebak berapa banyak bit di setiap tipe data.sumber
PRId64
,PRId32
makro didefinisikan?inttypes.h
PRIu64
danPRIu32
untuk bilangan bulat bertanda tangan.inttypes.h
standar? Bukanstdint.h
?leastX
danfastX
jenis (yang mungkin sebenarnya lebih luas dari yang ditunjukkan) yang wajib.%d
-> untukint
%u
-> untukunsigned int
%ld
-> untuklong int
ataulong
%lu
-> untukunsigned long int
ataulong unsigned int
atauunsigned long
%lld
-> untuklong long int
ataulong long
%llu
-> untukunsigned long long int
atauunsigned long long
sumber
Untuk jangka waktu lama (atau __int64) menggunakan MSVS, Anda harus menggunakan% I64d:
sumber
Itu karena% llu tidak berfungsi dengan baik di bawah Windows dan% d tidak dapat menangani bilangan bulat 64 bit. Saya sarankan menggunakan PRIu64 sebagai gantinya dan Anda akan menemukan itu portabel untuk Linux juga.
Coba ini sebagai gantinya:
Keluaran
sumber
int64_t
sebagai gantinya karena mungkin ada beberapa implementasi dengan panjang lebih besar dari panjangDi Linux itu
%llu
dan di Windows itu%I64u
Meskipun saya telah menemukan itu tidak berfungsi di Windows 2000, tampaknya ada bug di sana!
sumber
unsigned long long
datatype yang relatif baru (pada saat itu, dengan standar C99) tetapi kompiler C (termasuk MinGW / GCC) memanfaatkan runtime Microsoft C lama yang hanya mendukung spesifikasi C89. Saya hanya memiliki akses ke dokumen API Windows yang sangat lama dan cukup baru. Jadi sulit untuk mengatakan dengan tepat kapanI64u
dukungan dijatuhkan. Tapi sepertinya era XP.Kompilasi sebagai x64 dengan VS2005:
sumber
Selain apa yang ditulis orang tahun lalu:
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
Maka versi mingw Anda tidak default ke c99. Menambahkan flag compiler ini:
-std=c99
.sumber
Rupanya tidak ada yang datang dengan solusi multi-platform * selama lebih dari satu dekade sejak tahun 2008, jadi saya akan menambahkan milik saya 😛. Tolong unduh. (Bercanda. Saya tidak peduli.)
Larutan:
lltoa()
Cara Penggunaan:
Contoh OP:
Berbeda dengan
%lld
string format cetak, yang ini berfungsi untuk saya di bawah 32-bit GCC pada Windows.*) Yah, hampir multi-platform. Dalam MSVC, Anda tampaknya perlu
_ui64toa()
bukanlltoa()
.sumber
lltoa
.Hal-hal yang tidak standar selalu aneh :)
untuk bagian panjang yang panjang di bawah GNU itu
L
,ll
atauq
dan di bawah windows saya percaya itu
ll
hanyasumber
Hex:
Keluaran:
sumber
Nah, salah satu caranya adalah mengkompilasinya sebagai x64 dengan VS2008
Ini berjalan seperti yang Anda harapkan:
Untuk kode 32 bit, kita perlu menggunakan specifier format __int64 yang benar% I64u. Jadi itu menjadi.
Kode ini berfungsi untuk kompiler VS 32 dan 64 bit.
sumber