Shell‑скрипты, Ansible, deployment‑сценарии и другие подходы к автоматизации задач администрирования.
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
-
plazmagod
- рядовой
- Сообщения: 30
- Зарегистрирован: 2007-04-04 14:15:01
Непрочитанное сообщение
plazmagod » 2009-01-10 9:29:15
Встретился сейчас с ситауцией, когда expr`у становится плохо от таких выражений:
Код: Выделить всё
$ expr 662861 \* 4096
$ -1579888640 # в реале должно быть 2715078656
$ expr 56130355 \* 2048
$ -1009149952 # в реале должно быть 114954967040
Интересно, у меня одного так?!
plazmagod
-
Хостинг HostFood.ru
-
Хостинг HostFood.ru
Тарифы на хостинг в России, от 12 рублей:
https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.:
https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах:
https://www.host-food.ru/domains/
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 10:11:59
любое число большее чем 2147483648 будет отрицательным. Это справедливо для знакового целого числа (INT). Тут нужен либо беззнаковый целый тип, либо с плавающей запятой.
авк умеет работать с большими целыми числами
Код: Выделить всё
zg# awk 'BEGIN{print 662861 * 4096}'
2715078656
zg# awk 'BEGIN{print 56130355 * 2048}'
114954967040
zg#
zg
-
plazmagod
- рядовой
- Сообщения: 30
- Зарегистрирован: 2007-04-04 14:15:01
Непрочитанное сообщение
plazmagod » 2009-01-10 10:31:39
Точна. забыл

пользуюсь
а также
тоже работает. А какой способ менее требовательный к ресурсам? И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?
plazmagod
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 13:34:27
plazmagod писал(а):А какой способ менее требовательный к ресурсам?
тот который не вызывает внешних программ
plazmagod писал(а):И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?
никакую, это вычисляет сам шелл
zg
-
Гость
- проходил мимо
Непрочитанное сообщение
Гость » 2009-01-10 15:08:44
еще можно
это тоже самое, что и $((
expr)). Грубо говоря $((
expr)) == $(let
expr)
Гость
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 15:47:43
Гость писал(а):еще можно
поясни
Код: Выделить всё
zg# let 56130355 \* 2048
let: Команда не найдена.
zg# man let
No manual entry for let
zg#
zg
-
Гость
- проходил мимо
Непрочитанное сообщение
Гость » 2009-01-10 16:15:36
zg писал(а):Гость писал(а):еще можно
поясни
Код: Выделить всё
zg# let 56130355 \* 2048
let: Команда не найдена.
запускаешь в sh(1)?
Код: Выделить всё
(~). sh
$ let 56130355 \* 2048
114954967040
$ ^D
у bulitins'ов нет отдельных man'ов. Правда в случае
let команда даже не упоминается в sh(1) ;\
Гость
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 16:16:45
Код: Выделить всё
zg# sh -c 'let 56130355 \* 2048'
-1009149952
zg#
zg
-
Гость
- проходил мимо
Непрочитанное сообщение
Гость » 2009-01-10 16:22:22
zg писал(а):Код: Выделить всё
zg# sh -c 'let 56130355 \* 2048'
-1009149952
zg#
хм, у мя 8-CURRENT. На amd64 и i386 результат один и тот же — 114954967040.
Код: Выделить всё
(~). getconf LONG_MAX
9223372036854775807
(~). sh -c 'let 9223372036854775807 + 1'
-9223372036854775808
(~). sh -c 'let 9223372036854775806 + 1'
9223372036854775807
Гость
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 16:24:54
гм.. тогда лучше на авк делать, потому как не зависит от LONG_MAX
zg
-
Гость
- проходил мимо
Непрочитанное сообщение
Гость » 2009-01-10 16:30:00
Гость писал(а):Код: Выделить всё
(~). getconf LONG_MAX
9223372036854775807[/quote]сверился с i386. Все-таки это скорее LLONG_MAX, а не LONG_MAX.[quote="zg"]гм.. тогда лучше на авк делать, потому как не зависит от LONG_MAX[/quote]ну можно попробовать еще разбить число на несколько частей...
Гость
-
zg
- полковник
- Сообщения: 5845
- Зарегистрирован: 2007-12-07 13:51:33
- Откуда: Верх-Нейвинск
Непрочитанное сообщение
zg » 2009-01-10 16:50:43
Код: Выделить всё
zg# getconf LLONG_MAX
9223372036854775807
zg# awk 'BEGIN{print 9223372036854775807 + 1}'
9223372036854775808
zg#

zg
-
Гость
- проходил мимо
Непрочитанное сообщение
Гость » 2009-01-10 18:12:26
zg писал(а):Код: Выделить всё
zg# awk 'BEGIN{print 9223372036854775807 + 1}'
9223372036854775808
zg#

Код: Выделить всё
(~). awk 'BEGIN{print 9999999999999999 * 2}'
20000000000000000
(~). echo 9999999999999999 \* 2 | bc
19999999999999998
заметь, никак не определить, что это
приблеженное значение. Через десяток цифр правда awk(1) начинает добавлять экспоненту и где-то через сотню перестает считать вообще, а просто пишет
inf. А bc(1) и dc(1) считатют без каких-либо проблем.
Гость