14

Мне любопытно, что происходит, когда числовая переменная в bash увеличивается без намеренной остановки. Насколько большим может быть число? Будет ли он переполнен и станет отрицательным и просто продолжит увеличиваться вечно? Это сломается и скользит к остановке в некоторый момент?

Я использую процессор AMD x86_64, но я также был бы рад услышать 32-битные ответы, просто укажите, о чем вы говорите. Я использую Fedora21 64bit.

Я гуглил повсюду, но по какой-то странной причине не нашел этот специфический кусочек. Кажется, что это будет основная информация во всех руководствах и тому подобное.

3 ответа3

18

Это может зависеть от вашей версии bash, вашей ОС и архитектуры вашего процессора. Почему бы тебе не попробовать это самому? Установите переменную на (2 ^ 31)-1, затем увеличьте ее, установите на 2 ^ 32, затем увеличьте, установите на 2 ^ 64, затем увеличьте и т.д.

Здесь я только что попробовал сам на своем Core i7 Mac под OS X "El Capitan" v10.11.3, и похоже, что bash использует 64-битные целые числа со знаком.

$ uname -a
Darwin Spiff.local 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64
$ bash --version
bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
$
$ ((X=2**16)); echo $X
65536                        <-- okay, at least UInt16
$ ((X=2**32)); echo $X
4294967296                   <-- okay, at least UInt32
$ ((X=2**64)); echo $X
0                            <-- oops, not UInt64
$ ((X=(2**63)-1)); echo $X
9223372036854775807          <-- okay, at least SInt64
$ ((X++)); echo $X
-9223372036854775808         <-- overflowed and wrapped negative. Must be SInt64
3

Я настроил петлю. while return status is 0 increment a variable with addition and print the variable to stdout Я запустил ее как раз под 2 ^ 31, я пропустил и 2 ^ 31 и 2 ^ 32 без проблем, остановил ее, затем установил начальное значение равным чуть менее 2 ^ 63. Результатом было то, что он плавно перевернулся с 9.22e18 до -9.22e18 и продолжил увеличиваться в положительном направлении. (к нулю)

Просто чтобы проверить, что мое while [ $? -eq 0 ] фактически использовал состояние выхода команд в цикле while, не используя состояние выхода предыдущего скрипта или некоторую странность, я также запустил его с дополнительной командой внутри цикла, предназначенной для создания ненулевого состояния выхода в определенных приращениях.

Таким образом, он подписан, он будет переворачиваться, а не останавливаться на максимальном значении, и это происходит без каких-либо сообщений об ошибках. Таким образом, возможно оказаться в действительно бесконечном цикле. Он не ограничивает 64-битное оборудование и 64-битную ОС Linux старым 16 или 32-битным стандартом.

0

bash использует 64-битное целое число Таким образом, если вы увеличите значение переменной до максимального значения, она будет переполнена. Ниже мой тест с целым числом без знака и целым числом со знаком.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .