Arredondamentos...

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Arredondamentos...

Mensagem 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
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Re: Arredondamentos...

Mensagem 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
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Re: Arredondamentos...

Mensagem por carlos_dornelas »

Não é que funcionou mesmo!!!

Obrigado
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Re: Arredondamentos...

Mensagem por Hasse »

Foi um prazer amigo.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Re: Arredondamentos...

Mensagem 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.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: Arredondamentos...

Mensagem 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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: Arredondamentos...

Mensagem 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
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Re: Arredondamentos...

Mensagem 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"
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: Arredondamentos...

Mensagem 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. :)
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Re: Arredondamentos...

Mensagem 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
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: Arredondamentos...

Mensagem por Maligno »

Acho que isso não existe pro Clipper. Você teria de desenvolver. É meio chato, mas não é tão difícil.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Re: Arredondamentos...

Mensagem por fladimir »

Ok Maligno, grato.


:)Pos
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Re: Arredondamentos...

Mensagem 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!
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: Arredondamentos...

Mensagem 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.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Re: Arredondamentos...

Mensagem 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)
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Responder