Página 1 de 2

Arredondamentos...

Enviado: 06 Set 2009 18:34
por carlos_dornelas
Caros,

Como faço para que o programa não arredonde os valores decimais?

Exemplo: No calculo de 1% sobre o valor de R$ 178,82, faço do seguinte modo:

178,82 x 1 /100 = 1,7882, mas o programa mostra na tela 1,79 ( eu utilizo o pict '9999.99') e grava no dbf também 1,79.

Eu gostaria que o programa mostrasse R$ 1,78 e gravasse no .dbf também R$ 1,78...

Antonio Carlos

Re: Arredondamentos...

Enviado: 06 Set 2009 21:09
por Hasse
Uma das formas é:

Código: Selecionar todos

x := 178,82 x 1 /100   ==>>  1,7882
Y1 := x * 100  ==>> 178,82
Y2 := Int( Y1 )  ==>> 178
Y3 := Y2 / 100  ==>>  1,78
resumindo tudo numa só linha:

Código: Selecionar todos

Y3 := Int( X * 100 ) / 100

Re: Arredondamentos...

Enviado: 06 Set 2009 22:29
por carlos_dornelas
Não é que funcionou mesmo!!!

Obrigado

Re: Arredondamentos...

Enviado: 06 Set 2009 22:59
por Hasse
Foi um prazer amigo.

Re: Arredondamentos...

Enviado: 07 Set 2009 10:56
por alxsts
Saudações!

Só achei estranho o motivo pelo qual voce quer fazer isto...
Nos critérios padrões de arredondamento, se quero arredondar um valor para duas casas decimais, a terceira casa depois do ponto decimal é avaliada da seguinte forma: se entre 0 e 4, a segunda casa decimal permanece como está; se entre 5 e 9, acresce-se 1 a esta segunda casa decimal. Portanto, 1,7882 arrendondado para duas casas decimais é igual a 1,79. Essa regra é utilizada de forma geral, no comércio, indústria, serviços e governo. Se não usar isto, pode até gerar valores de impostos de forma incorreta.

Re: Arredondamentos...

Enviado: 07 Set 2009 11:24
por alaminojunior
Como faço para que o programa não arredonde os valores decimais?
Na verdade o que o colega precisava era truncar o valor e não arredondar, e muitas vezes é preciso truncar valores sim.

Re: Arredondamentos...

Enviado: 07 Set 2009 11:33
por Maligno
alxsts escreveu:Essa regra é utilizada de forma geral, no comércio, indústria, serviços e governo.
Que eu saiba, o tipo de arredondamento mais comumente utilizado nas instituições financeiras e bancárias é o "arredondamento do banqueiro", que compensa perdas e ganhos nos casos em que o valor termina em 5; o meio termo pra cima e pra baixo. Em algumas linguagens de programação esse é o padrão. Sem ele, perde-se ou ganha-se de forma fixa. E se todos os valores terminam em 5? Alguém sempre ganhará em prejuízo de alguém.

Nesse tipo de arredondamento o valor será arredondado pra cima quando o valor do dígito vizinho for ímpar, e para baixo quando for par.

Código: Selecionar todos

Exemplos:
1,225 --> 1,22
1,235 --> 1,24

Re: Arredondamentos...

Enviado: 07 Set 2009 21:51
por alxsts
Saudações!

Agradeço aos colegas pelas informações. Realmente já tive que truncar vários valores e arredondar somente ao final do cálculo. Quanto à regra do "arredondamento do banqueiro", eu desconhecia. Foi uma novidade para mim. Mas, pelos testes que efetuei, o Clipper não usa esta regra e sim a que mencionei anteriormente:

Código: Selecionar todos

    Exemplos:                      
    1,225 --> 1,22
    1,235 --> 1,24

Código: Selecionar todos

> ? Transform(1.224, "@E 9999.99")
      "   1,22"
> ? Transform(1.225, "@E 9999.99")
      "   1,23"
> ? Transform(1.234, "@E 9999.99")
      "   1,23"
> ? Transform(1.235, "@E 9999.99")
      "   1,24"
> ? Transform(178.42, "@E 9999.99")
      " 178,42"
> ? Transform(178.92, "@E 9999.99")
      " 178,92"
> ? Transform(178.99, "@E 9999.99")
      " 178,99"
> ? Transform(178.99, "@E 9999.999")
      " 178,990"
> ? Transform(178.999, "@E 9999.999")
      " 178,999"
> ? Transform(178.999, "@E 9999.99")
      " 179,00"

Re: Arredondamentos...

Enviado: 07 Set 2009 22:04
por Maligno
Realmente. O Clipper não utiliza o "arredondamento do banqueiro". Se o final for 5, o valor é sempre arredondado pra cima. Mas o do "banqueiro" é um método bem mais justo, principalmente quando há um volume muito grande de cálculos a arredondar. Pode-se perceber isso no meu exemplo, melhor formulado:

Código: Selecionar todos

Exemplos         Diferença
--------------   ---------
1,225 --> 1,22      -0,005 (perdeu)
1,235 --> 1,24      +0,005 (ganhou)
                 ---------
    Resultado:       0,000 (empate)
Mas note que a função Transform() arredonda apenas para visualização. Internamente nada muda se o valor residir numa variável. Aí é que se torna necessário usar Round() ou algum outro artifício para produzir o arredondamento. Principalmente em comparações de valores, onde o Clipper sempre se perde (normalmente se converte em string antes de comparar).

Aliás, cálculo em ponto-flutuante é algo extremamente complexo. E nesse campo, muito do que se utiliza no Clipper é proveniente de um pacote de ponto-flutuante licenciado da Microsoft, ainda na época em que isso era totalmente emulado (não havia co-processador matemático (ou FPU) embutido, como hoje em dia). Mas isso é coisa do tempo do guaraná com rolha. :)

Re: Arredondamentos...

Enviado: 07 Set 2009 22:09
por fladimir
Interessante essa discussão...

Então se eu quiser ter o arredondamento do banqueiro terei q montar uma função específica ? Ou já existe em alguma lib ?

....

:)Pos

Re: Arredondamentos...

Enviado: 07 Set 2009 22:11
por Maligno
Acho que isso não existe pro Clipper. Você teria de desenvolver. É meio chato, mas não é tão difícil.

Re: Arredondamentos...

Enviado: 07 Set 2009 22:16
por fladimir
Ok Maligno, grato.


:)Pos

Re: Arredondamentos...

Enviado: 07 Set 2009 22:32
por alxsts
Queiram por gentileza me perdoar mas, penso que a Round() produz o mesmo efeito de Transform() ou Picture. Vejam:

Código: Selecionar todos

> ? Round( 1.224,2 )
               1.22
> ? Round( 1.225,2 )
               1.23
> ? Round( 1.234,2 )
               1.23
> ? Round( 1.235,2 )
               1.24
> ? Round( 178.42,2 )
             178.42
> ? Round( 178.92,2 )
             178.92
> ? Round( 178.99,2 )
             178.99
> ? Round( 178.999,2 )
             179.00
>
Parabens mais uma vez ao Clipper on Line! Mato Grosso, Paraná e São Paulo (no mímimo) ligados. Isso é que é ser On Line. Viva a Independencia!

Re: Arredondamentos...

Enviado: 07 Set 2009 22:46
por Maligno
Sim. A função Round() produz o mesmo efeito que Transform(). Eu apenas quis enfatizar que internamente nada muda antes de uma atribuição direta à variável que contenha o valor. Aliás, nem poderia ser diferente. Não poderia haver dois pesos e duas medidas.

Apenas acrescentando um lembrete à idéia de criar um "arredondamento do banqueiro" em Clipper, caso o colega leve adiante esse projeto: é preciso tomar o cuidado de, antes do armazenamento em banco de dados, fazer esse arredondamento. Caso contrário, haveria uma divergência de valores e alguns problemas "meio estranhos" no decorrer da execução do programa.

Re: Arredondamentos...

Enviado: 07 Set 2009 23:50
por sygecom
Bom vou colocar mais lenha nessa fogueira.

Na verdade existe uma normal que regulariza isso que é a Norma ABNT(Associação Brasileira de Normas Técnicas) NBR 5891 de Dezembro de 1977 que diz o seguinte:
Status : Em Vigor

1. OBJETIVO

Esta norma tem por fim estabelecer as regras de arredondamento na Numeração Decimal.

2. REGRAS DE ARREDONDAMENTO

2.1 Quando o algarismo imediatamente seguinte ao último algarismo a ser conservado for inferior a 5,
o último algarismo a ser conservado permanecerá sem modificação.

Exemplo:

1,333 3 arredondado à primeira decimal tornar-se-á 1,3.

2.2 Quando o algarismo imediatamente seguinte ao último algarismo a ser conservado for superior a 5, ou, sendo 5, for seguido de no mínimo um algarismo diferente de zero, o último algarismo a ser conservado deverá ser aumentado de uma unidade.

Exemplo:

1,666 6 arredondado à primeira decimal tornar-se-á: 1,7.
4,850 5 arredondados à primeira decimal tornar-se-ão : 4,9.

2.3 Quando o algarismo imediatamente seguinte ao último algarismo a ser conservado for 5 seguido de zeros, dever-se-á arredondar o algarismo a ser conservado para o algarismo par mais próximo. Conseqüentemente, o último a ser retirado, se for ímpar, aumentará uma unidade.

Exemplo:

4,550 0 arredondados à primeira decimal tornar-se-ão: 4,6.

2.4 Quando o algarismo imediatamente seguinte ao último a ser conservado for 5 seguido de zeros, se for par o algarismo a ser conservado, ele permanecerá sem modificação.

Exemplo:

4,850 0 arredondados à primeira decimal tornar-se-ão: 4,8.
Em função disso temos que cuidar muito ao utlilizar algo contrario, pricipalmente quando se for em um documento fiscal, eu utilizo uma função para arredondamento diferenciado, mas apenas quando não é documentos fiscais ou armazenamento.

Código: Selecionar todos

FUNCTION MY_ROUND(VALOR,DEC)
DEFAULT dec := 2
dec := 7-dec
valor := substr(str(valor,20,7),1,(20-dec))
RETURN val(valor)