Ответ 1
Единственное различие между подписанной математикой без знака в C и JVM возникает с помощью оператора смены вправо. Для неподписанной математики вы используете логический сдвиг (поскольку вы не хотите расширения знака), тогда как для подписанной математики вы выполняете арифметический сдвиг (который сохраняет знак). Это одна из красавиц Арифметика двух дополнений.
Исходя из этого, все, что вам нужно сделать, это изменить оператор Java/ Scala >>
для оператора >>>
, и вы получите один и тот же ответ, по-разному. Однако, в зависимости от того, что вы делаете, все может быть проблематично, когда вы пытаетесь что-то сделать с результатом, например. если вы хотите напечатать его как целое без знака.
Скажем, вы хотите сделать математику с "unsigned" longs в Scala и напечатать результат в конце. Просто используйте обычный длинный, используйте >>>
(логический сдвиг) вместо >>
, а затем преобразуйте его в нечто другое в конце, которое может представлять значение без знака. Вы можете использовать библиотеку, например, предложенную в ответе @rightfold, или вы можете просто сделать что-то простое:
val x = Long.MaxValue // declare my "unsigned" long
// do some math with it ...
val y = x + 10
// Convert it to the equivalent Scala BigInt
def asUnsigned(unsignedLong: Long) =
(BigInt(unsignedLong >>> 1) << 1) + (unsignedLong & 1)
x
// Long = 9223372036854775807
asUnsigned(y)
// res1: scala.math.BigInt = 9223372036854775817
Если вы просто используете Int
s, вам даже не нужно преобразовывать в BigInt
в конце, так как Long
может удерживать ответ. Просто используйте метод, который @BrianRoach предлагает в своем комментарии выше для преобразования значения Int
"unsigned" в эквивалентный Long
путем маскировки байтов более высокого порядка. Однако, опять же, вы не должны делать конверсию, пока не будете абсолютно необходимы. Даже при использовании 64-разрядной JVM на 64-битном процессоре операции умножения и деления целого числа будут медленнее для Long
(64-разрядной), чем для Int
(32-разрядной). (См. Этот вопрос для получения дополнительной информации: Имеют ли 64-битные целые числа менее эффективные, чем 32-битные целые числа в JVM?).