Как указать максимальное значение, представляемое для unsigned
целочисленного типа?
Я хотел бы знать, как инициализировать min
в цикле ниже, который итеративно вычисляет минимальную и максимальную длину из некоторых структур.
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
}
так что в первый раз через сравнение minLen >= n
.
int(^uint(0) >> 1) // largest int
извлеченный из golang.org/doc/effective_go.html#printingОтветы:
https://groups.google.com/group/golang-nuts/msg/71c307e4d73024ce?pli=1
Немецкая часть:
Согласно комментарию @ CarelZA:
источник
math
: golang.org/pkg/math/#pkg-constants , вам,math.MaxInt32
скорее всего, понадобится .int
тип имеет длину 32 бита в 32-битной системе и 64 бита в 64-битной системе. Смотрите здесь .https://golang.org/ref/spec#Numeric_types для ограничений физического типа.
Максимальные значения определены в математическом пакете, поэтому в вашем случае: math.MaxUint32
Следите за тем, чтобы не было переполнения - приращение выше максимума вызывает циклический переход.
источник
uint
, а неuint32
.len
Иcap
использованиеint
неint32
так что я хочу использовать что - то , что соответствует размеру тех , на всех архитектурах.math/const.go
определяет группу,Max<type>
но ни одного для любогоuint
или `int.uint(len(...)) < thing.minLen
но я не знаю,uint64(int)
останется ли определенное поведение и останется ли оно.Я бы использовал
math
пакет для получения максимального значения и минимального значения:Выход:
источник
int64
переполнения int, что происходит, если вы явно не вводите константы перед интерполяцией строк. Используйтеint64(math.MaxInt64)
вместо этого, см stackoverflow.com/questions/16474594/...Первоначально я использовал код, взятый из ветки обсуждения, которую @nmichaels использовал в своем ответе. Сейчас я использую несколько иной расчет. Я добавил несколько комментариев на случай, если у кого-то еще есть тот же запрос, что и у @Arijoon
Последние два шага работают из-за того, как положительные и отрицательные числа представлены в арифметике с дополнением до двух. Раздел спецификации языка Go о числовых типах отсылает читателя к соответствующей статье в Википедии . Я не читал этого, но я узнал о двух дополнениях из книги Чарльза Петцольда «Код» , которая представляет собой очень доступное введение в основы компьютеров и программирования.
Я поместил приведенный выше код (без большинства комментариев) в небольшой пакет целочисленных математических вычислений .
источник
Краткое резюме:
Задний план:
Как я полагаю, вы знаете,
uint
тип имеет тот же размер, что иuint32
илиuint64
, в зависимости от платформы, на которой вы находитесь. Обычно их версию без размера можно использовать только тогда, когда нет риска приблизиться к максимальному значению, так как версия без спецификации размера может использовать «собственный» тип, в зависимости от платформы, который, как правило, работает быстрее.Обратите внимание, что он имеет тенденцию быть «быстрее», потому что использование неродного типа иногда требует дополнительных вычислений и проверки границ, выполняемых процессором для имитации большего или меньшего целого числа. Имея это в виду, имейте в виду, что производительность процессора (или оптимизированного кода компилятора) почти всегда будет лучше, чем добавление собственного кода проверки границ, поэтому, если есть какой-либо риск, что он вступит в игру, он может сделать имеет смысл просто использовать версию с фиксированным размером и позволить оптимизированной эмуляции справиться с любыми последствиями этого.
С учетом вышесказанного, все еще есть ситуации, когда полезно знать, с чем вы работаете.
Пакет " math / bits " содержит размер
uint
в битах. Чтобы определить максимальное значение, сдвиньте1
это количество бит, минус 1. т.е.(1 << bits.UintSize) - 1
Обратите внимание, что при вычислении максимального значения
uint
вам, как правило, необходимо явно поместить его вuint
переменную (или более крупную), иначе компилятор может выйти из строя, так как по умолчанию он будет пытаться присвоить это вычисление подписаннойint
(где, как следует очевидно, не подошло бы), поэтому:Это прямой ответ на ваш вопрос, но есть также пара связанных расчетов, которые могут вас заинтересовать.
Согласно спецификации ,
uint
иint
всегда одинаковый размер.Таким образом, мы также можем использовать эту константу для определения максимального значения
int
, взяв тот же ответ и разделив его на2
вычитание1
. то есть:(1 << bits.UintSize) / 2 - 1
И минимальное значение
int
, сдвинувшись1
на это количество бит и разделив результат на-2
. то есть:(1 << bits.UintSize) / -2
В итоге:
MaxUint:
(1 << bits.UintSize) - 1
MaxInt:
(1 << bits.UintSize) / 2 - 1
MinInt:
(1 << bits.UintSize) / -2
полный пример (должен быть таким же, как показано ниже)
источник
/2
часть - это то, что исключает этот бит из рассмотрения при вычислении размера min / max для int64)Из математической библиотеки: https://github.com/golang/go/blob/master/src/math/const.go#L39
источник
Один из способов решить эту проблему - получить начальные точки из самих значений:
источник
Легкий пакет содержит их (а также ограничения на другие типы int и некоторые широко используемые целочисленные функции):
источник
источник
Используйте константы, определенные в математическом пакете :
источник