expr - Баг или фича?!

Программирование на sh, быть может немного про альтернативные языки
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
plazmagod
рядовой
Сообщения: 30
Зарегистрирован: 2007-04-04 14:15:01

expr - Баг или фича?!

Непрочитанное сообщение plazmagod » 2009-01-10 9:29:15

Встретился сейчас с ситауцией, когда expr`у становится плохо от таких выражений:

Код: Выделить всё

$ expr 662861 \* 4096
$ -1579888640                            # в реале должно быть 2715078656
$ expr 56130355 \* 2048
$ -1009149952                            # в реале должно быть 114954967040
Интересно, у меня одного так?!

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.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
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 10:11:59

любое число большее чем 2147483648 будет отрицательным. Это справедливо для знакового целого числа (INT). Тут нужен либо беззнаковый целый тип, либо с плавающей запятой.

авк умеет работать с большими целыми числами

Код: Выделить всё

zg# awk 'BEGIN{print 662861 * 4096}'
2715078656
zg# awk 'BEGIN{print 56130355 * 2048}'
114954967040
zg#

plazmagod
рядовой
Сообщения: 30
Зарегистрирован: 2007-04-04 14:15:01

Re: expr - Баг или фича?!

Непрочитанное сообщение plazmagod » 2009-01-10 10:31:39

Точна. забыл :)
пользуюсь

Код: Выделить всё

echo "56130355*2048" | bc
114954967040
а также

Код: Выделить всё

echo $((56130355*2048))
114954967040
тоже работает. А какой способ менее требовательный к ресурсам? И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 13:34:27

plazmagod писал(а):А какой способ менее требовательный к ресурсам?
тот который не вызывает внешних программ
plazmagod писал(а):И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?
никакую, это вычисляет сам шелл

Гость
проходил мимо

Re: expr - Баг или фича?!

Непрочитанное сообщение Гость » 2009-01-10 15:08:44

еще можно

Код: Выделить всё

let 56130355 \* 2048
это тоже самое, что и $((expr)). Грубо говоря $((expr)) == $(let expr)

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 15:47:43

Гость писал(а):еще можно
поясни

Код: Выделить всё

zg# let 56130355 \* 2048
let: Команда не найдена.
zg# man let
No manual entry for let
zg#

Гость
проходил мимо

Re: expr - Баг или фича?!

Непрочитанное сообщение Гость » 2009-01-10 16:15:36

zg писал(а):
Гость писал(а):еще можно
поясни

Код: Выделить всё

zg# let 56130355 \* 2048
let: Команда не найдена.
запускаешь в sh(1)?

Код: Выделить всё

(~). sh
$ let 56130355 \* 2048
114954967040
$ ^D
zg писал(а):

Код: Выделить всё

zg# man let
No manual entry for let
zg#
у bulitins'ов нет отдельных man'ов. Правда в случае let команда даже не упоминается в sh(1) ;\

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 16:16:45

Код: Выделить всё

zg# sh -c 'let 56130355 \* 2048'
-1009149952
zg#

Гость
проходил мимо

Re: expr - Баг или фича?!

Непрочитанное сообщение Гость » 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
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 16:24:54

Код: Выделить всё

zg# getconf LONG_MAX
2147483647
zg#
гм.. тогда лучше на авк делать, потому как не зависит от LONG_MAX

Гость
проходил мимо

Re: expr - Баг или фича?!

Непрочитанное сообщение Гость » 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
Откуда: Верх-Нейвинск

Re: expr - Баг или фича?!

Непрочитанное сообщение zg » 2009-01-10 16:50:43

Код: Выделить всё

zg# getconf LLONG_MAX
9223372036854775807
zg# awk 'BEGIN{print 9223372036854775807 + 1}'
9223372036854775808
zg#
:smile:

Гость
проходил мимо

Re: expr - Баг или фича?!

Непрочитанное сообщение Гость » 2009-01-10 18:12:26

zg писал(а):

Код: Выделить всё

zg# awk 'BEGIN{print 9223372036854775807 + 1}'
9223372036854775808
zg#
:smile:

Код: Выделить всё

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