Bagaimana cara menentukan nilai maksimum yang dapat diwakili untuk unsigned
tipe integer?
Saya ingin tahu bagaimana menginisialisasi min
dalam loop di bawah ini yang secara iteratif menghitung panjang min dan max dari beberapa struct.
var minLen uint = ???
var maxLen uint = 0
for _, thing := range sliceOfThings {
if minLen > thing.n { minLen = thing.n }
if maxLen < thing.n { maxLen = thing.n }
}
if minLen > maxLen {
// If there are no values, clamp min at 0 so that min <= max.
minLen = 0
}
sehingga pertama kali melalui perbandingan minLen >= n
,.
int(^uint(0) >> 1) // largest int
diekstrak dari golang.org/doc/effective_go.html#printingJawaban:
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
Bagian erat:
Sesuai komentar @ CarelZA:
sumber
math
: golang.org/pkg/math/#pkg-constants , yang paling Anda inginkanmath.MaxInt32
.int
jenisnya panjang 32 bit pada sistem 32 bit dan 64 bit panjang pada sistem 64 bit. Lihat di sini .https://golang.org/ref/spec#Numeric_types untuk batas tipe fisik.
Nilai-nilai maks didefinisikan dalam paket matematika sehingga dalam kasus Anda: math.MaxUint32
Berhati-hatilah karena tidak ada overflow - penambahan max yang lalu menyebabkan sampul.
sumber
uint
, bukanuint32
. Thelen
dancap
penggunaanint
tidakint32
jadi saya ingin menggunakan sesuatu yang sesuai dengan ukuran mereka pada semua arsitektur.math/const.go
mendefinisikan sekelompokMax<type>
tetapi tidak ada untuk salahuint
atau `int.uint(len(...)) < thing.minLen
tetapi saya tidak tahu apakahuint64(int)
itu perilaku tetap dan akan didefinisikan.Saya akan menggunakan
math
paket untuk mendapatkan nilai maksimal dan nilai minimal:Ouput:
sumber
int64
Overflow int keduanya , yang terjadi jika Anda tidak secara eksplisit mengetikkan konstanta sebelum interpolasi string. Gunakanint64(math.MaxInt64)
sebaliknya, lihat stackoverflow.com/questions/16474594/…Saya awalnya menggunakan kode yang diambil dari utas diskusi yang @nmichaels gunakan dalam jawabannya. Saya sekarang menggunakan perhitungan yang sedikit berbeda. Saya telah memasukkan beberapa komentar jika ada orang lain yang memiliki pertanyaan yang sama dengan @Arijoon
Dua langkah terakhir bekerja karena bagaimana angka positif dan negatif direpresentasikan dalam aritmatika komplemen dua. Bagian spesifikasi bahasa Go pada tipe Numerik merujuk pembaca ke artikel Wikipedia yang relevan . Saya belum membaca itu, tapi saya belajar tentang pelengkap dua dari buku Code oleh Charles Petzold , yang merupakan pengantar yang sangat mudah diakses dengan dasar-dasar komputer dan pengkodean.
Saya memasukkan kode di atas (minus sebagian besar komentar) ke dalam paket matematika integer kecil .
sumber
Ringkasan cepat:
Latar Belakang:
Seperti yang saya kira Anda tahu,
uint
jenisnya adalah ukuran yang samauint32
atauuint64
, tergantung pada platform Anda. Biasanya, seseorang akan menggunakan versi unsized ini hanya ketika tidak ada risiko mendekati nilai maksimum, karena versi tanpa spesifikasi ukuran dapat menggunakan tipe "asli", tergantung pada platform, yang cenderung lebih cepat.Perhatikan bahwa itu cenderung "lebih cepat" karena menggunakan tipe non-asli kadang-kadang membutuhkan matematika tambahan dan pemeriksaan batas yang harus dilakukan oleh prosesor, untuk meniru bilangan bulat yang lebih besar atau lebih kecil. Dengan mengingat hal tersebut, ketahuilah bahwa kinerja prosesor (atau kode yang dioptimalkan kompiler) hampir selalu akan lebih baik daripada menambahkan kode pemeriksaan batas Anda sendiri, jadi jika ada risiko prosesor ikut bermain, itu mungkin membuat akal untuk hanya menggunakan versi ukuran tetap, dan biarkan emulasi yang dioptimalkan menangani dampak dari itu.
Dengan itu, masih ada beberapa situasi di mana berguna untuk mengetahui apa yang Anda kerjakan.
Paket " math / bits " berisi ukuran
uint
, dalam bits. Untuk menentukan nilai maksimum, bergeser1
dengan banyak bit itu, minus 1. yaitu:(1 << bits.UintSize) - 1
Perhatikan bahwa ketika menghitung nilai maksimum
uint
, Anda biasanya harus memasukkannya secara eksplisit ke dalamuint
variabel (atau lebih besar), jika tidak kompiler akan gagal, karena akan gagal untuk menetapkan penetapan perhitungan ke dalam tanda tanganint
(di mana, sebagaimana seharusnya menjadi jelas, itu tidak akan cocok), jadi:Itulah jawaban langsung untuk pertanyaan Anda, tetapi ada juga beberapa perhitungan terkait yang mungkin menarik bagi Anda.
Menurut spesifikasi ,
uint
danint
ukurannya selalu sama.Jadi kita juga dapat menggunakan konstanta ini untuk menentukan nilai maksimum
int
, dengan mengambil jawaban yang sama dan membaginya dengan2
kemudian mengurangi1
. yaitu:(1 << bits.UintSize) / 2 - 1
Dan nilai minimum
int
, dengan menggeser1
banyak bit dan membagi hasilnya dengan-2
. yaitu:(1 << bits.UintSize) / -2
Singkatnya:
MaxUint:
(1 << bits.UintSize) - 1
Maksimal:
(1 << bits.UintSize) / 2 - 1
MinInt:
(1 << bits.UintSize) / -2
contoh lengkap (harus sama dengan di bawah ini)
sumber
/2
bagian inilah yang menghilangkan bit itu dari pertimbangan ketika menghitung ukuran min / maks untuk int64)Dari math lib: https://github.com/golang/go/blob/master/src/math/const.go#L39
sumber
Salah satu cara untuk mengatasi masalah ini adalah dengan mendapatkan titik awal dari nilai-nilai itu sendiri:
sumber
Paket ringan berisi mereka (serta batas tipe int lainnya dan beberapa fungsi integer yang banyak digunakan):
sumber
sumber