Скала не может сделать добавление на долго - PullRequest
0 голосов
/ 15 мая 2019

Я не могу сделать добавление для длинного типа.

scala или процессор неправильно управляет знаком

scala> var i="-1014570924054025346".toLong
i: Long = -1014570924054025346

scala> i=i+92233720368547758L
i: Long = -922337203685477588
scala> var i=9223372036854775807L
i: Long = 9223372036854775807

scala> i=i+5
i: Long = -9223372036854775804

Первый тест, в которомотрицательное число не переходит в положительное для меня проблема

Ответы [ 2 ]

2 голосов
/ 15 мая 2019

Я не до конца понял вопрос, но для первого примера вы получите ожидаемый результат. Что происходит во втором примере, число Long оказывается максимальным значением для Long (т.е. Long.MaxValue), поэтому, по существу, когда у вас есть другое положительное число, оно переполняется:

scala> Long.MaxValue
res4: Long = 9223372036854775807L

scala> Long.MaxValue + 1
res7: Long = -9223372036854775808L // which is Long.MinValue

scala> Long.MinValue + 4
res8: Long = -9223372036854775804L // which is the result that you get

Другими словами:

9223372036854775807L + 5 

эквивалентно:

Long.MaxValue + 5 

что эквивалентно:

Long.MinValue + 4 // because (Long.MaxValue + 1) = Long.MinValue

, что равно -9223372036854775804L

1 голос
/ 15 мая 2019

Если вам действительно нужно использовать такие большие числа, вы можете попробовать использовать BigInt

scala> val x = BigInt(Long.MaxValue)
x: scala.math.BigInt = 9223372036854775807

scala> x + 1
res6: scala.math.BigInt = 9223372036854775808

scala> x + 5
res11: scala.math.BigInt = 9223372036854775812

scala> x + 10
res8: scala.math.BigInt = 9223372036854775817

scala> x * 1000
res10: scala.math.BigInt = 9223372036854775807000

scala> x * x
res9: scala.math.BigInt = 85070591730234615847396907784232501249

scala> x * x * x * x
res13: scala.math.BigInt = 7237005577332262210834635695349653859421902880380109739573089701262786560001

scala> 

Документация по BigInt довольно мала. Тем не менее, я считаю, что это в основном целое число с бесконечной точностью (может поддерживать столько цифр, сколько вам нужно). Сказав это, вероятно, в какой-то момент будет предел. Существует комментарий к BigDecimal, который содержит больше документации, что около 4934 цифр может быть некоторое расхождение между BigDecimal и BigInt.

Я оставлю это кому-то другому, чтобы выяснить, является ли x ^ 4 значением, показанным выше.

О, я чуть не забыл твой тест отрицательного числа, я выровнял сумму с инициализацией, чтобы было проще визуализировать, что результат кажется правильным:

scala> val x =    BigInt("-1014570924054025346")
x: scala.math.BigInt    = -1014570924054025346
scala>                   x + 92233720368547758L
res15: scala.math.BigInt = -922337203685477588

scala> 

Что касается типов Ints, Long и аналогичных типов, они ограничены по размеру из-за количества битов, к которым они привязаны. Int обычно 32-битные, а long 64-битные.

Проще визуализировать, когда вы смотрите на них в шестнадцатеричном формате. со знаком Байт (в 8 битах) имеет максимальное положительное значение 0x7F (127). Когда вы добавляете один к нему, вы получаете 0x80 (-128). Это потому, что мы используем «Наиболее значимый бит» как индикатор того, является ли число положительным или отрицательным.

Если тот же байт был интерпретирован как без знака , тогда 0x7F (127) все равно станет 0x80, когда к нему добавится 1. Однако, поскольку мы интерпретируем его как беззнаковое, это будет эквивалентно 128. Мы можем продолжать добавлять один, пока не получим 0xFF (255), и в этом случае, если мы добавим еще 1, мы снова окажемся в 0x00, что, конечно, 0 .

Вот некоторые ссылки, которые объясняют это более подробно:

Википедия - дополнение к двум

Корнельский университет - что дополняет пара

Переполнение стека - что такое дополнение 2 с

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...