Как добавить знак минус к результату при преобразовании отрицательного числа в строку
Что проверяют
Обычно это часть задачи «переведите число в строку без strconv». Интервьюер смотрит, как вы обрабатываете знак, ноль и граничное значение, на котором ломается наивное решение. Следом почти всегда спрашивают, что будет с math.MinInt64.
Как отвечать
Сначала скажите, что в продакшене это strconv.Itoa(n) или strconv.FormatInt(n, 10): знак они ставят сами, а strconv.AppendInt пишет в готовый []byte без лишних аллокаций. fmt.Sprintf("%d", n) тоже работает, но медленнее. Затем пишите ручную версию:
- знак отдельно: запоминаете
neg := n < 0и дальше работаете с модулем; - модуль без переполнения:
-nдляmath.MinInt64снова даётmath.MinInt64, потому что числа 9223372036854775808 вint64нет. Решение:u := uint64(n), и при отрицательномnвзятьu = -u. Беззнаковая арифметика в Go оборачивается по модулю 2⁶⁴, и результат верен даже на границе; - цифры с конца: буфер
var buf [20]byteвмещает 19 цифр и знак, заполняете его справа налево черезbuf[i] = byte('0' + u%10)иu /= 10; - ноль: цикл в форме «сделать, потом проверить», иначе для нуля выйдет пустая строка;
- минус в конце: если
neg, ставите'-'перед первой цифрой и возвращаетеstring(buf[i:]).
Другой приём: не брать модуль, а считать цифры на отрицательном числе. В Go остаток сохраняет знак делимого, -7 % 10 равно -7, поэтому цифра это -(n % 10).
Проверочные значения назовите вслух: 0, -1, 10, -10, math.MaxInt64, math.MinInt64.
Где спотыкаются
Пишут "-" + strconv.Itoa(-n). На math.MinInt64 это даёт строку с двумя минусами, и именно этот случай проверяют.
Превращают цифру в символ через string(d). Это конвертация кода символа: string(5) даёт управляющий символ, а не «5», и если d имеет тип int, go vet на такое ругается.
Собирают строку конкатенацией s = string(c) + s в цикле. Каждая итерация создаёт новую строку, для 19 цифр это терпимо, но буфер с заполнением с конца здесь естественнее, и интервьюер это отметит.