Как получить bc (1) для печати ведущего нуля?



Я делаю что-то вроде следующего в Makefile:



echo "0.1 + 0.1" | bc


(в реальном файле числа являются динамическими, конечно)



печати .2 но я хочу, чтобы он напечатал 0.2.



Я хотел бы сделать это, не прибегая к sed но я не могу найти, как получить bc для печати нуля. Или это bc просто не в состоянии сделать это?

666   11  

11 ответов:

вы также можете прибегнуть к awk в формате:

 echo "0.1 + 0.1" | bc | awk '{printf "%f", }'

или с awk сам делает математику:

 echo "0.1 0.1" | awk '{printf "%f",  + }'

Это может сработать для вас:

echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc

после быстрого взгляда на источник (см. bc_out_num(), строка 1461), я не вижу очевидного способа сделать ведущий 0 получить печать, если целочисленная часть 0. Если я что-то не пропустил, это поведение не зависит от параметра, который можно изменить с помощью флага командной строки.

короткий ответ: нет, я не думаю, что есть способ сделать bc печать чисел так, как вы хотите.

Я не вижу ничего плохого в использовании sed если вы все еще хотите использовать bc. Следующее не выглядит так ужасно, ИМХО:

[me@home]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2

если вы действительно хотите, чтобы избежать sed, и eljunior это!--10--> и choroba это!--10--> предложения довольно аккуратны, но они требуют настройки в зависимости от значения, чтобы избежать конечных нулей. Это может быть или не быть проблемой для вас.

Я не могу найти ничего о формате вывода в документации. Вместо sed, вы также можете обратиться к printf:

printf '%3.1f\n' $(bc<<<0.1+0.1)
$ bc -l <<< 'x=-1/2; if (length (x) == scale (x) && x != 0) { if (x < 0) print "-",0,-x else print 0,x } else print x'

Это чисто bc. Он обнаруживает ведущий ноль, сравнивая результат length С scale выражения. Он работает как на положительном, так и на отрицательном числе.

Этот также будет обрабатывать отрицательные числа:

echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\././'

это только использует bc, и работает с отрицательными числами:

bc <<< "x=-.1; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";

попробуйте это:

for y in "0" "0.1" "-0.1" "1.1" "-1.1"; do
  bc <<< "x=$y; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
  echo;
done

наверное, bc на самом деле не лучший "скамейка калькулятор" для современной эпохи. Другие языки дадут вам больше контроля. Вот рабочие примеры, которые печатают значения в диапазоне (-1.0..+1.0) с нулем. Эти примеры используют bc,AWK и Python 3.

#!/bin/bash

echo "using bc"
time for (( i=-2; i<=+2; i++ ))
   {
   echo $(bc<<<"scale=1; x=$i/2; if (x==0||x<=-1||x>=1) { print x } else { if (x<0) { print \"-0\";-x } else { print \"0\";x } } ")
   }
echo

echo "using awk"
time for (( i=-2; i<=+2; i++ ))
   {
   echo $(echo|awk "{printf \"%.1f\",$i/2}")
   }  
echo

echo "using Python"
time for (( i=-2; i<=+2; i++ ))
   {
   echo $(python3<<<"print($i/2)")
   }

обратите внимание, что версия Python примерно в 10 раз медленнее, если это имеет значение.

для положительных чисел, это может быть так же просто, как печать (строка) ноль:

$ echo '"0";0.1+0.1' | bc
0.2

избегайте нуля, если число больше (или равно) 1:

$ echo 'x=0.1+0.1;  if(x<1){"0"};  x' | bc
0.2

это становится немного сложнее, если число может быть отрицательным:

echo 'x= 0.3 - 0.5 ; s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1) {"0"};x' | bc
-0.2

вы можете определить функцию и добавить ее в библиотеке:

$ echo 'define leadzero(x){auto s;
        s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
        return(x)};
        leadzero(2.1-12.4)' | bc
-10.3

$ echo 'define leadzero(x){auto s;
        s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
        return(x)};
        leadzero(0.1-0.4)' | bc
-0.3

строительство на potongs ответ,

для дробных результатов:

echo "x=0.1 + 0.1; if(x<1 && x > 0) print 0; x" | bc -l

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

echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'

это должно работать для всех случаев, когда результаты:

  • "-.123"
  • ".123"
  • "-1.23"
  • "1.23"

объяснение:

  1. для всего, что только начинается с -. заменить -. С -0.

  2. для всего, что только начинается с . заменить . С 0.

Comments

    Ничего не найдено.