Один 1 байт может быть от 0
до 255
. Я собираюсь изменить масштаб с 0
на 7
. Я сделал это:
bit8 := uint8(136)
// To re-scale 1 byte from 0 to 2^3-1 i.e. 0 to 7
bit3 := bit8 / 0xff * 0b0111
В результате bit3
будет 0
, но я ожидаю, что это будет 3
или 4
в зависимости от округления в меньшую или большую сторону. Поскольку точное значение с плавающей запятой будет 136/255*7 = 3.733333333
.
Как я могу достичь желаемого результата? На данном этапе округление в большую или меньшую сторону не имеет значения. Что удобно, то и хорошо.
Я хочу, чтобы операция была максимально эффективной. Потому что это будет сделано внутри цикла. Таким образом, решения, подобные приведенным ниже, не являются оптимальными:
bit8 := uint8(136)
// To re-scale 1 byte from 0 to 2^3-1 i.e. 0 to 7
bit3 := uint8(float64(bit8) / 255.0 * 7.0)
Разве это не то, что вы описываете в подписи log2()
?
Ваша первая попытка равна нулю, потому что вы выполняете целочисленное деление, а x/255 всегда будет равно нулю. Сначала вы можете умножить на 7, но тогда вам понадобится больший тип int.
«Я ожидаю, что это будет 3 или 4, в зависимости от округления в меньшую или большую сторону». Целочисленное деление не выполняет «округление» некоторых промежуточных значений с плавающей запятой, таких как 3,73333.
@matt Какой самый быстрый способ сделать это?
Возьмите верхние 3 бита байта (округляя вниз):
bit3 := bit8 >> 5
На всякий случай, как я могу изменить его, чтобы округлить?
@Megidd Округление целочисленного деления (вместо усечения) . Метод зависит от того, хотите ли вы округлить, до ближайшего значения или как-то еще.
Другой способ взглянуть на это: ваше масштабирование 256 до 8, то есть x*8/256, сокращается до x/2^5 или x>>5.
@matt Это было потрясающее объяснение. Поразительнй.
bit3 := bit8 & 7
?