Максимально числовое значение в bash

На курсах “Администратор ПК c Linux” на одной из лекций, посвященной языку bash, преподаватель предложил нам написать дома скрипт, который будет выводить максимальное целое числовое значение, которым может оперировать bash. Как и следовало ожидать слушатели, у которых нет технического образования с этой задачей не справились. Даже не то, чтобы не справились, а просто пытались решить ее путем прибавления единицы к числу в бесконечном цикле в надежде, что когда будет достигнуто максимальное значение, скрипт остановится, и на экране будет максимальное число, которое они выводили командой echo. Один из слушателей курса рассказал, что оставил такой скрипт работать, а когда через час подошел к компьютеру, скрипт все еще выводил значения на экран.

На самом деле все решается очень просто, если знать некоторые моменты, такие как двоичная система счисления, знаковый бит и некоторые другие. В итоге скрипт выполняется почти мгновенно и выдает точное число. Сначала приведу текст скрипта, а затем небольшие пояснения к нему.

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
a=1
i=1
while [ $a -gt 0 ]
do
  let a=a*2
  let i++
done
let a=a-1
echo $a

Этот скрипт выводит максимальное число bash, которое равно - 9223372036854775807. Таким образом, можно сказать, что тип числовых данных соответствует типу bigint в других языках программирования. Напомню, что в bash переменные не имеют типа, что на самом деле не редкость. Так переменные языка PHP, изучить, который можно в школе программирования на ПХП, также не имеют типа. Но вернемся к скрипту.

Данный скрипт в цикле умножает число (начиная с единицы) на 2 и проверяет не является ли полученное число отрицательным. Чтобы понять почему вдруг положительное число должно стать отрицательным, нужно понимать, как устроена двоичная система, так как именно в ней выполняются все операции в процессоре компьютера. На определенном шаге, единица (единица - в двоичной системе), которая при каждом умножении на два - сдвигается влево на один разряд, в итоге попадает в знаковый бит регистра и число становиться отрицательным. Когда все разряды содержат нули, а знаковый содержит единицу - это максимальное отрицательное число -9223372036854775808. Чтобы из него получить максимальное положительное нужно вычесть из него единицу. Кто изучал двоичную систему тот уже понял как работает скрипт, поэтому более подробно вдаваться в подробности не буду.

Если кто-то не понял почему так и хочет разобраться - оставляйте комментарии - с удовольствием помогу.

Статьи и новости схожей тематики:

Комментариев: 4

  1. Pe1ro:

    Я понял, но не понял )
    Описываемая технология ясна, не ясно с чем связано это ограничение. Ведь ясно же, что любое число (даже большее, чем 9223372036854775807) можно перевести в двоичную систему исчисления. Объясните?

    Ответить

    Igorka Reply:

    Даже не знаю как тут объяснить. Любая среда программирования (назову так условно) оперирует числами определенной разрядности. Всегда есть максимальное число (математический тип данных) с которым среда может выполнять операции. Ограничения связаны как с аппаратной частью (разрядность процессора, шины данных и прочее) так и с программной реализацией тех или иных сред программирования. Примерно так.

    Ответить

  2. riso:

    Хорошее решение, но я не пойму зачем вы задали переменную i ?

    Ответить

    Igorka Reply:

    Переменная i задавалась чтобы посмотреть количество итераций, которое показывает разрядность двоичного числа. Согласен, что здесь нужно либо вывести это число, либо убрать переменную совсем.

    Ответить

Оставьте свой отзыв