Вопрос проверяет понимание битовых операций и представления чисел со знаком в Go.
В Go числа со знаком хранятся в дополнительном коде (two's complement). Старший бит (знаковый) равен 1 для отрицательных чисел и 0 для положительных. Сдвиг вправо на 31 бит для int32 (или 63 для int64) заполняет все биты значением знакового бита, создавая маску: 0 для положительных, -1 (все единицы) для отрицательных.
Формула abs = (n + mask) ^ mask работает так: для положительных n mask=0, результат n. Для отрицательных mask=-1, n + mask = n - 1, затем XOR с -1 инвертирует все биты, что даёт -n - 1 + 1 = -n.
package main
import "fmt"
func absInt32(n int32) int32 {
mask := n >> 31
return (n + mask) ^ mask
}
func main() {
fmt.Println(absInt32(-5)) // 5
fmt.Println(absInt32(3)) // 3
fmt.Println(absInt32(0)) // 0
}Для int64 используйте сдвиг на 63. Этот метод эффективен, так как не использует условные операторы и работает за константное время.
Такой подход полезен в высокопроизводительном коде, где важна скорость и предсказуемость, например, в обработке сигналов, графике или встраиваемых системах. Однако для обычных приложений math.Abs читаемее и безопаснее.
Вывод: Используйте битовую реализацию abs только при необходимости максимальной производительности и полном понимании работы с дополнительным кодом. В остальных случаях предпочтительнее стандартная функция math.Abs.