BC - multiplicação automática completa da precisão

10

Alto, preciso testar minha calculadora de precisão arbitrária e bcparece um bom parâmetro para comparar, no entanto, bctrunca o resultado de cada multiplicação para o que parece ser a escala máxima dos operandos envolvidos.

Existe uma maneira rápida de desativar isso ou definir automaticamente a escala de cada multiplicação para a soma das escalas dos fatores, para que não perca precisão?

Se você tiver uma solução mais elegante para isso envolvendo algo diferente bc, agradeceria por compartilhar.

Exemplo:

$ bc <<< '1.5 * 1.5'
2.2

A resposta real é 2,25.

PSkocik
fonte
Intimamente relacionado à operação de flutuação com bc? .
manatwork

Respostas:

12

Você pode controlar a escala que bcsai com o scale=<#>argumento.

$ echo "scale=10; 5.1234 * 5.5678" | bc
28.52606652

$ echo "scale=5; 5.1234 * 5.5678" | bc
28.52606

Usando seu exemplo:

$ bc <<< 'scale=2; 1.5 * 1.5'
2.25

Você também pode usar a -lopção (graças a @manatwork) que inicializará a escala para 20 em vez do padrão de 0. Por exemplo:

$ bc -l <<< '1.5 * 1.5'
2.25

$ bc -l <<< '1.52 * 1.52'
2.3104

Você pode ler mais sobre scalena bcpágina de manual .

slm
fonte
5
Ou menos: bc -l. “ -L (A carta ell.) Definir as funções matemáticas e escala initialize a 20, em vez de zero defeito” - bcespecificação
manatwork
@ manatwork - obrigado, não percebeu essa mudança.
SLM
Obrigado. Acho que poderia definir a escala como 2147483647 (que é igual a INT_MAX), o que bc diz que é o valor máximo de escala que posso definir (estou muito longe nos meus testes), mas acho que testarei apenas com números inteiros e forneceremos os benefícios de desempenho resultantes do uso de números de tamanho dinâmico.
PSKocik
1
Para multiplicação bc, a escala do resultado é exatamente min(max(sx,sy,scale),sx+sy)onde sxe sysão as escalas de xe yem x*y. A configuração scale=scale(x)+scale(y)fornecerá a precisão máxima necessária. Definir a escala para um número maior (como 1000) não aumentará a escala do resultado. A variável de escala afeta apenas s diretamente. O resultado da divisão scale=1000; a/1criará um resultado com 1000 dígitos decimais (após o ponto), independentemente da escala de a anterior.
Isaac
1

Tente o seguinte:

$ bc
scale=10
1.5 * 1.5
2.25

Pesquise bc's man pela variável scale

DavAlPi
fonte
0

Eu criei essa função bash que não exibirá zeros à direita

calc () { MAX_PRECISION=20; bc <<< "scale=$MAX_PRECISION; scale = scale($@); $@"; }

Exemplo: calc 1.25^3= 1.953125

Vartan
fonte