Страница 1 из 1
expr - Баг или фича?!
Добавлено: 2009-01-10 9:29:15
plazmagod
Встретился сейчас с ситауцией, когда expr`у становится плохо от таких выражений:
Код: Выделить всё
$ expr 662861 \* 4096
$ -1579888640 # в реале должно быть 2715078656
$ expr 56130355 \* 2048
$ -1009149952 # в реале должно быть 114954967040
Интересно, у меня одного так?!
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 10:11:59
zg
любое число большее чем 2147483648 будет отрицательным. Это справедливо для знакового целого числа (INT). Тут нужен либо беззнаковый целый тип, либо с плавающей запятой.
авк умеет работать с большими целыми числами
Код: Выделить всё
zg# awk 'BEGIN{print 662861 * 4096}'
2715078656
zg# awk 'BEGIN{print 56130355 * 2048}'
114954967040
zg#
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 10:31:39
plazmagod
Точна. забыл

пользуюсь
а также
тоже работает. А какой способ менее требовательный к ресурсам? И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 13:34:27
zg
plazmagod писал(а):А какой способ менее требовательный к ресурсам?
тот который не вызывает внешних программ
plazmagod писал(а):И какую команду на исполнение вызывает запись вида $((expr1*expr2)) ?
никакую, это вычисляет сам шелл
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 15:08:44
Гость
еще можно
это тоже самое, что и $((
expr)). Грубо говоря $((
expr)) == $(let
expr)
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 15:47:43
zg
Гость писал(а):еще можно
поясни
Код: Выделить всё
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
у bulitins'ов нет отдельных man'ов. Правда в случае
let команда даже не упоминается в sh(1) ;\
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 16:16:45
zg
Код: Выделить всё
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
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 16:24:54
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]ну можно попробовать еще разбить число на несколько частей...
Re: expr - Баг или фича?!
Добавлено: 2009-01-10 16:50:43
zg
Код: Выделить всё
zg# getconf LLONG_MAX
9223372036854775807
zg# awk 'BEGIN{print 9223372036854775807 + 1}'
9223372036854775808
zg#

Re: expr - Баг или фича?!
Добавлено: 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) считатют без каких-либо проблем.