Как мне получить bc (1) для печати начального нуля? - PullRequest
57 голосов
/ 06 декабря 2011

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

echo "0.1 + 0.1" | bc

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

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

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

Ответы [ 11 ]

39 голосов
/ 06 декабря 2011

Вы также можете использовать awk для форматирования:

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

или с помощью самого awk, выполняющего математические вычисления:

 echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
33 голосов
/ 06 декабря 2011

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

echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc
23 голосов
/ 06 декабря 2011

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

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

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

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

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

9 голосов
/ 06 декабря 2011

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

printf '%3.1f\n' $(bc<<<0.1+0.1)
3 голосов
/ 31 июля 2015
$ 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 выражения.Работает как на положительном, так и на отрицательном числе.

3 голосов
/ 14 марта 2014

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

echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./'
2 голосов
/ 08 мая 2018

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

$ 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
2 голосов
/ 03 ноября 2017

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

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

  • "-. 123"
  • ". 123"
  • "- 1,23"
  • "1,23"

Объяснение:

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

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

1 голос
/ 21 апреля 2015

Вероятно, 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 раз медленнее, если это имеет значение.

1 голос
/ 09 июня 2013

используется только 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
...