Saya hanya ingin tahu, jika saya ingin membagi a dengan b, dan tertarik pada hasil c dan sisanya (misalnya saya punya jumlah detik dan ingin membaginya menjadi menit dan detik), apa cara terbaik untuk pergi tentang itu?
Apakah itu
int c = (int)a / b;
int d = a % b;
atau
int c = (int)a / b;
int d = a - b * c;
atau
double tmp = a / b;
int c = (int)tmp;
int d = (int)(0.5+(tmp-c)*b);
atau
mungkinkah ada fungsi magis yang memberikan keduanya sekaligus?
double
(item terakhir Anda) menurut saya seperti ide yang buruk, Anda akan berakhir dengan angka yang tidak sesuai, dan dapat merugikan Anda dalam kinerja dan ukuran yang dapat dieksekusi (selalu menjadi masalah bagi saya pada sistem tertanam tertentu).Jawaban:
Pada x86, sisanya adalah produk sampingan dari divisi itu sendiri sehingga setiap kompiler yang setengah layak harus dapat menggunakannya (dan tidak melakukan
div
lagi). Ini mungkin dilakukan pada arsitektur lain juga.sumber
idivl
instruksi dan menggunakan hasil di eax dan edx. Saya akan terkejut jika tidak.idivl
instruksi, tetapi dengan-O1
atau lebih tinggi, Anda mendapatkan satu. Seperti yang dikatakan manual, "Tanpa opsi pengoptimalan apa pun ... Pernyataan bersifat independen" .std::div
mengembalikan struktur dengan hasil dan sisa.sumber
long long
, tetapi sangat mungkin kompilator Anda memilikilong long
kelebihan bebanstd::div
sebagai ekstensi.Setidaknya pada x86, g ++ 4.6.1 hanya menggunakan IDIVL dan mendapatkan keduanya dari instruksi tunggal tersebut.
Kode C ++:
kode x86:
sumber
/=
- Anda mungkin perlu menggunakan variabel sementara untuk menjaga pembagian terlebih dahulu.Contoh pengujian kode div () dan gabungan divisi & mod. Saya mengkompilasi ini dengan gcc -O3, saya harus menambahkan panggilan ke doNothing untuk menghentikan kompiler dari mengoptimalkan semuanya (output akan menjadi 0 untuk solusi divisi + mod).
Ambillah dengan sebutir garam:
Hasil: 150
Hasil: 25
sumber
Selain keluarga fungsi std :: div yang disebutkan di atas , ada juga keluarga fungsi std :: remquo , mengembalikan rem -ainder dan mendapatkan quo -tient melalui pointer yang diteruskan.
[Sunting:] Sepertinya std :: remquo tidak benar-benar mengembalikan hasil bagi sama sekali.
sumber
Semuanya sama, solusi terbaik adalah solusi yang dengan jelas mengungkapkan niat Anda. Begitu:
mungkin yang terbaik dari tiga opsi yang Anda berikan. Namun, seperti disebutkan dalam jawaban lain,
div
metode ini akan menghitung kedua nilai untuk Anda sekaligus.sumber
Anda tidak dapat mempercayai g ++ 4.6.3 di sini dengan integer 64 bit pada platform intel 32 bit. a / b dihitung dengan panggilan ke divdi3 dan% b dihitung dengan panggilan ke moddi3. Saya bahkan dapat memberikan contoh yang menghitung a / b dan ab * (a / b) dengan panggilan ini. Jadi saya menggunakan c = a / b dan ab * c.
Metode div memberikan panggilan ke fungsi yang menghitung struktur div, tetapi panggilan fungsi tampaknya tidak efisien pada platform yang memiliki dukungan perangkat keras untuk tipe integral (mis. 64 bit integer pada platform intel / amd 64 bit).
sumber
Anda dapat menggunakan modulus untuk mendapatkan sisanya. Padahal jawaban @cnicutar terkesan lebih bersih / lugas.
sumber