Apakah saya benar mengatakan bahwa perbedaan antara bilangan bulat yang ditandatangani dan tidak ditandatangani adalah:
- Unsigned dapat memiliki nilai positif yang lebih besar, dan tidak ada nilai negatif.
- Unsigned menggunakan bit terkemuka sebagai bagian dari nilai, sedangkan versi yang ditandatangani menggunakan bit paling kiri untuk mengidentifikasi apakah angka positif atau negatif.
- bilangan bulat yang ditandatangani dapat menampung angka positif dan negatif.
Adakah perbedaan lain?
language-agnostic
integer
unsigned
signed
Shimmy Weitzhandler
sumber
sumber
Jawaban:
Iya.
Ada berbagai cara untuk mewakili bilangan bulat yang ditandatangani. Yang paling mudah untuk divisualisasikan adalah dengan menggunakan bit paling kiri sebagai bendera ( tanda dan besarnya ), tetapi yang lebih umum adalah pelengkap dua . Keduanya digunakan di sebagian besar mikroprosesor modern - floating point menggunakan tanda dan besarnya, sedangkan aritmatika integer menggunakan komplemen dua itu.
Iya
sumber
Saya akan membahas perbedaan pada tingkat perangkat keras, pada x86. Ini sebagian besar tidak relevan kecuali Anda sedang menulis kompiler atau menggunakan bahasa assembly. Tapi itu menyenangkan untuk diketahui.
Pertama, x86 memiliki dukungan asli untuk representasi komplemen dua angka yang ditandatangani. Anda dapat menggunakan representasi lain tetapi ini akan membutuhkan lebih banyak instruksi dan umumnya membuang-buang waktu prosesor.
Apa yang saya maksud dengan "dukungan asli"? Pada dasarnya saya maksudkan bahwa ada satu set instruksi yang Anda gunakan untuk nomor yang tidak ditandatangani dan satu set yang Anda gunakan untuk nomor yang ditandatangani. Nomor yang tidak ditandai dapat duduk di register yang sama dengan nomor yang ditandatangani, dan memang Anda dapat mencampur instruksi yang ditandatangani dan yang tidak ditandatangani tanpa mengkhawatirkan prosesor. Terserah kompiler (atau programmer perakitan) untuk melacak apakah suatu nomor ditandatangani atau tidak, dan gunakan instruksi yang sesuai.
Pertama, angka komplemen dua memiliki properti yang penambahan dan pengurangannya sama dengan nomor yang tidak ditandatangani. Tidak ada bedanya apakah angkanya positif atau negatif. (Jadi, Anda hanya melanjutkan dan
ADD
danSUB
nomor Anda tanpa khawatir.)Perbedaan mulai terlihat ketika datang ke perbandingan. x86 memiliki cara sederhana untuk membedakannya: di atas / di bawah ini menunjukkan perbandingan yang tidak ditandatangani dan lebih besar / kurang dari yang menunjukkan perbandingan yang ditandatangani. (Misalnya
JAE
berarti "Lompat jika di atas atau sama" dan tidak ditandatangani.)Ada juga dua set instruksi perkalian dan pembagian untuk menangani bilangan bulat yang ditandatangani dan tidak ditandatangani.
Terakhir: jika Anda ingin memeriksa, katakanlah, melimpah, Anda akan melakukannya secara berbeda untuk nomor yang ditandatangani dan tidak ditandatangani.
sumber
Dia hanya bertanya tentang ditandatangani dan tidak ditandatangani. Tidak tahu mengapa orang menambahkan hal-hal tambahan dalam hal ini. Biarkan saya memberi tahu Anda jawabannya.
Unsigned: Ini hanya terdiri dari nilai-nilai non-negatif yaitu 0 hingga 255.
Ditandatangani: Terdiri dari nilai-nilai negatif dan positif tetapi dalam berbagai format seperti
Dan penjelasan ini adalah tentang sistem angka 8-bit.
sumber
Hanya beberapa poin untuk kelengkapan:
jawaban ini hanya membahas representasi bilangan bulat. Mungkin ada jawaban lain untuk floating point;
representasi dari angka negatif dapat bervariasi. Yang paling umum (sejauh ini - hampir universal saat ini) yang digunakan saat ini adalah pelengkap dua . Representasi lain termasuk komplemen seseorang (sangat langka) dan magnitudo yang ditandatangani (sangat jarang - mungkin hanya digunakan pada karya museum) yang hanya menggunakan bit tinggi sebagai indikator tanda dengan bit tetap mewakili nilai absolut dari nomor tersebut.
Ketika menggunakan komplemen dua, variabel dapat mewakili rentang yang lebih besar (per satu) dari angka negatif daripada angka positif. Ini karena nol termasuk dalam angka 'positif' (karena bit tanda tidak disetel untuk nol), tetapi bukan angka negatif. Ini berarti bahwa nilai absolut dari angka negatif terkecil tidak dapat direpresentasikan.
ketika menggunakan komplemen atau besaran yang ditandatangani, Anda dapat memiliki angka nol sebagai angka positif atau negatif (yang merupakan salah satu dari beberapa alasan mengapa representasi ini biasanya tidak digunakan).
sumber
Menurut apa yang kami pelajari di kelas, bilangan bulat yang ditandatangani dapat mewakili angka positif dan negatif, sedangkan bilangan bulat yang tidak ditandatangani hanya non-negatif.
Misalnya, melihat angka 8-bit :
nilai yang tidak ditandatangani
0
ke255
nilai yang ditandatangani berkisar dari
-128
hingga127
sumber
Semuanya kecuali poin 2 sudah benar. Ada banyak notasi berbeda untuk ints yang ditandatangani, beberapa implementasi menggunakan yang pertama, yang lain menggunakan yang terakhir dan yang lain menggunakan sesuatu yang sama sekali berbeda. Itu semua tergantung pada platform yang Anda gunakan.
sumber
Perbedaan lainnya adalah ketika Anda mengonversi bilangan bulat dengan ukuran berbeda.
Misalnya, jika Anda mengekstrak integer dari aliran byte (katakanlah 16 bit untuk kesederhanaan), dengan nilai yang tidak ditandatangani, Anda bisa melakukan:
(mungkin harus melemparkan 2 nd byte, tapi aku menebak compiler akan melakukan hal yang benar)
Dengan nilai yang ditandatangani, Anda harus khawatir tentang ekstensi tanda dan lakukan:
sumber
Secara umum itu benar. Tanpa mengetahui lebih banyak tentang mengapa Anda mencari perbedaan, saya tidak bisa memikirkan pembeda lain antara ditandatangani dan tidak ditandatangani.
sumber
Di atas dan di atas yang dikatakan orang lain, di C, Anda tidak bisa melimpahi integer yang tidak ditandatangani; perilaku didefinisikan sebagai modulus aritmatika. Anda dapat melimpahi integer yang ditandatangani dan, secara teori (meskipun tidak dalam praktiknya pada sistem arus utama), overflow dapat memicu kesalahan (mungkin mirip dengan pembagian dengan kesalahan nol).
sumber
sumber
(sebagai jawaban untuk pertanyaan kedua) Dengan hanya menggunakan bit tanda (dan bukan komplemen 2's), Anda dapat berakhir dengan -0. Tidak terlalu cantik.
sumber
Bilangan bulat yang ditandatangani di C mewakili angka. Jika
a
danb
merupakan variabel dari tipe integer yang ditandatangani, standar tidak akan pernah mengharuskan kompiler membuat ekspresia+=b
menyimpan menjadia
apa pun selain jumlah aritmatika dari nilai masing-masing. Yang pasti, jika jumlah aritmatika tidak cocoka
, prosesor mungkin tidak dapat meletakkannya di sana, tetapi standar tidak akan meminta kompiler memotong atau membungkus nilai, atau melakukan hal lain untuk masalah ini jika nilai melebihi batas untuk tipenya. Perhatikan bahwa meskipun standar tidak memerlukannya, implementasi C diizinkan untuk menjebak aliran aritmatika dengan nilai yang ditandatangani.Bilangan bulat tak bertanda di C berperilaku sebagai cincin aljabar abstrak bilangan bulat yang merupakan modul kongruen dengan kekuatan dua, kecuali dalam skenario yang melibatkan konversi ke, atau operasi dengan, tipe yang lebih besar. Mengubah bilangan bulat dari ukuran apa pun menjadi tipe 32-bit yang tidak ditandatangani akan menghasilkan anggota yang sesuai dengan hal-hal yang kongruen dengan bilangan bulat itu mod 4.294.967.296. Alasan mengurangi 3 dari 2 menghasilkan 4.294.967.295 adalah bahwa menambahkan sesuatu yang kongruen ke 3 ke sesuatu yang kongruen ke 4.294.967.295 akan menghasilkan sesuatu yang kongruen dengan 2.
Jenis cincin aljabar abstrak seringkali merupakan hal yang mudah untuk dimiliki; Sayangnya, C menggunakan signness sebagai faktor penentu apakah suatu tipe harus berperilaku sebagai cincin. Lebih buruk lagi, nilai-nilai yang tidak ditandatangani diperlakukan sebagai angka daripada anggota dering ketika dikonversi ke tipe yang lebih besar, dan nilai yang tidak ditandatangani lebih kecil daripada
int
dikonversi ke angka ketika ada aritmatika dilakukan pada mereka. Jikav
adalahuint32_t
yang sama4,294,967,294
, makav*=v;
harus membuatv=4
. Sayangnya, jikaint
64 bit, maka tidak ada yang tahu apa yangv*=v;
bisa dilakukan.Mengingat standar seperti itu, saya akan menyarankan menggunakan tipe yang tidak ditandai dalam situasi di mana seseorang ingin perilaku yang terkait dengan cincin aljabar, dan tipe yang ditandatangani ketika seseorang ingin mewakili angka. Sangat disayangkan bahwa C menarik perbedaan seperti itu, tetapi mereka adalah apa adanya.
sumber
Bilangan bulat tak bertanda jauh lebih mungkin menangkap Anda dalam perangkap tertentu daripada bilangan bulat yang ditandatangani. Perangkap berasal dari fakta bahwa sementara 1 & 3 di atas benar, kedua jenis bilangan bulat dapat diberi nilai di luar batas dari apa yang dapat "ditahan" dan itu akan dikonversi secara diam-diam.
Ketika Anda menjalankan ini, Anda akan mendapatkan output berikut meskipun kedua nilai ditugaskan ke -1 dan dinyatakan berbeda.
sumber
Satu-satunya perbedaan yang dijamin antara nilai yang ditandatangani dan yang tidak ditandatangani dalam C adalah bahwa nilai yang ditandatangani bisa negatif, 0 atau positif, sedangkan yang tidak ditandatangani hanya bisa 0 atau positif. Masalahnya adalah bahwa C tidak mendefinisikan format tipe (jadi Anda tidak tahu bahwa integer Anda ada dalam komplemen dua). Sebenarnya dua poin pertama yang Anda sebutkan salah.
sumber
Anda harus menggunakan Integer yang tidak ditandatangani saat pemrograman pada Sistem Tertanam. Dalam loop, ketika tidak perlu untuk bilangan bulat yang ditandatangani, menggunakan bilangan bulat yang tidak ditandatangani akan menghemat yang diperlukan untuk merancang sistem tersebut.
sumber