Арифметические операторы применяются к числовым значениям и дают результат того же типа, что и первый операнд. Четыре стандартных арифметических оператора (+, -, *, /) применяются к целым числам, числам с плавающей точкой и сложным типам; + также относится к строкам. Битовые логические операторы и операторы сдвига применяются только к целым числам.
+ sum integers, floats, complex values, strings
- difference integers, floats, complex values
* product integers, floats, complex values
/ quotient integers, floats, complex values
% remainder integers
& bitwise AND integers
| bitwise OR integers
^ bitwise XOR integers
&^ bit clear (AND NOT) integers
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
Целочисленные операторы
Для двух целочисленных значений x и y целочисленное отношение q = x / y и остаток r = x % y удовлетворяют следующим соотношениям:
x = q*y + r и |r| < |y|
х / у усекается до нуля ("усеченное деление", "truncated division").
x y x / y x % y
5 3 1 2
-5 3 -1 -2
5 -3 -1 2
-5 -3 1 -2
Единственное исключение из этого правила состоит в том, что если дивиденд x является самым отрицательным значением для типа int типа x, частное q = x / -1 равно x (и r = 0) из-за переполнения двух-комплементного целого числа из двух дополнений:
x, q
int8 -128
int16 -32768
int32 -2147483648
int64 -9223372036854775808
Если делитель является константой, он не должен быть нулевым. Если делитель равен нулю во время выполнения, возникает паника во время выполнения. Если дивиденд неотрицательный и делитель имеет постоянную степень 2, деление может быть заменено сдвигом вправо, а вычисление остатка может быть заменено побитовой операцией И (bitwise AND):
x x / 4 x % 4 x >> 2 x & 3
11 2 3 2 3
-11 -2 -3 -3 1
Операторы сдвига смещают левый операнд на число смещения, указанное правым операндом. Они реализуют арифметические сдвиги, если левый операнд представляет собой целое число со знаком, и логические сдвиги, если это целое число без знака. Там нет верхнего предела на счет сдвига. Сдвиги ведут себя так, как будто левый операнд смещен n раз на 1 для числа сдвигов n. В результате x << 1 совпадает с x*2, а x >> 1 совпадает с x/2, но усекается до отрицательной бесконечности.
Для целочисленных операндов унарные операторы +, - и ^ определяются следующим образом:
+x это 0 + x
-x negation это 0 - x
^x bitwise complement это m ^ x с m = "все биты устанавливаются в 1" для беззнакового (unsigned) x
и m = -1 для x со знаком (signed)
Переполнение целых чисел
Для целочисленных значений без знака (unsigned integer) операции +, -, * и << вычисляются по модулю 2n, где n - ширина в битах типа целого числа без знака. Грубо говоря, эти целочисленные операции без знака отбрасывают старшие биты при переполнении, и программы могут полагаться на "циклический переход".
Для целых чисел со знаком операции +, -, *, / и << могут легально переполняться, и результирующее значение существует и детерминировано определяется представлением целого числа со знаком, операцией и ее операндами. Переполнение не вызывает паники во время выполнения. Компилятор может не оптимизировать код при условии, что переполнения не происходит. Например, он может не предполагать, что x < x + 1 всегда верно.
Операторы для чисел с плавающей точкой
Для чисел с плавающей точкой и комплексных чисел +x - это то же самое, что и x, а -x - отрицание x. Результат деления с плавающей запятой или сложного деления на ноль не указан вне стандарта IEEE-754; возникновение паники во время выполнения зависит от реализации.
Реализация может объединять несколько операций с плавающей запятой в одну объединенную операцию, возможно, между операторами, и производить результат, который отличается от значения, полученного путем выполнения и округления инструкций по отдельности. Явное преобразование типа с плавающей точкой округляет до точности целевого типа, предотвращая слияние, которое отбрасывает это округление.
Например, в некоторых архитектурах предусмотрена инструкция «FMA», которая вычисляет x * y + z без округления промежуточного результата x * y. Следующие примеры показывают, когда реализация Go может использовать эту инструкцию:
// FMA включена при вычислении r, потому что x*y явно не округляется:
r = x*y + z
r = z; r += x*y
t = x*y; r = t + z
*p = x*y; r = *p + z
r = x*y + float64(z)
// FMA выключена при вычислении r, потому что она будет пропускать округление x*y:
r = float64(x*y) + z
r = z; r += float64(x*y)
t = float64(x*y); r = t + z
Конкатенация строк
Строки могут быть объединены с помощью оператора + или оператора присвоения +=
s := "hi" + string(c)
s += " and good bye"
Добавление строки создает новую строку путем объединения операндов.
Читайте также:
- Спецификация Go: операторы, приоритет операторов
- Спецификация Go: лексические элементы
- Спецификация Go: выражения (expressions) - операнды, квалифицированные идентификаторы
Комментариев нет:
Отправить комментарий