Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Spitzer
Usuário Nível 2
Usuário Nível 2
Mensagens: 60
Registrado em: 15 Ago 2003 04:56
Localização: Nova Fátima - PR

Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Spitzer »

Olá!

Pessoal, o texto ficará longo, mas por favor, leiam porque não consigo achar uma solução (solução tenho até mais de uma, mas preciso de uma que tome o menor tempo para ser processada).

Estou com um problema de lógica pura num programa Clipper.
Preciso desenvolver um RPA onde os encargos não são descontados do prestador de serviços, porque a empresa arca com estes encargos.
Mas, mesmo assim, a empresa quer que estes encargos sejam destacados no RPA como se descontados tivessem sido.
Então preciso ajustar para cima o valor contratado de forma que, ao aplicar os descontos, dê o valor líquido contratado.
É mais ou menos como utilizar a opção “Atingir Meta” do Excel.
Pensei numa regrinha de três jogando valores altos, e fictícios, para poder estabelecer a relação percentual entre o valor bruto (que eu devo encontrar) e o valor líquido (que é o valor contratado), mas já cheguei ao consenso que não é possível, pois o IR, por exemplo, só existirá após uma faixa de valor, então pode ser que o valor líquido contratado não atinja IR, mas que quando eu chegar ao valor bruto, atinja, assim como há descontos que obedecem a certo teto, como é o caso do INSS.
Incrementar de centavo a centavo até chegar ao valor bruto determinado, também fica inviável, pois a rotina de cálculos faz acessos à base de dados para buscar limites, atualizar cálculos cumulativos, buscar tetos, enfim, e incrementando os valores centavo a centavo, a rotina seria executada milhares de vezes e levaria muito tempo, tempo este que o prestador de serviços não aguardará.

Vou montar um pequeno exemplo para ficar mais claro tudo aí em cima:
VALOR BRUTO: 713,70
DESCONTOS: 3,57
INSS RETIDO: 15,70
ICMS – SUBSTITUIÇÃO: 68,51
VALOR LÍQUIDO: 625,92

Então, o valor que será passado ao programa será R$ 625,92, que é o que foi contratado com o prestador de serviços, e o programa deverá chegar aos 713,70.
Lógico que todo o cálculo estará num laço, mas este laço deverá ser executado o menor número de vezes possível, senão a performance degradará muito (já testei isto).

Bom, depois da longa história, vem a pergunta:
PELO AMOR DE DEUS, COMO SAIO DE UM VALOR LÍQUIDO PARA CHEGAR NUM VALOR BRUTO QUE DESCONHEÇO, ONDE O VALOR LÍQUIDO É O VALOR BRUTO MENOS OS ENCARGOS, DE FORMA QUE A ROTINA SEJA EXECUTADA NO MENOR NÚMERO DE VEZES POSSÍVEL?

Desde já, muito obrigado mesmo!


Abraços,
Ademir Spitzer
Abraços,
Ademir Spitzer
Manuel Luis Modernel
Usuário Nível 2
Usuário Nível 2
Mensagens: 66
Registrado em: 02 Mar 2008 20:40
Localização: São José do Rio Preto - SP

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Manuel Luis Modernel »

Meu amigo Spitzer !

Inicia tua regra de 3 fazendo com que o teu valor liquido (R$ 625,92) seja o 100% e o R$ 713,70 o resulatado final, o "X" da questão.

Sabes onde isso é feito e VC pode tirar uma duvida, nas contas de Luz onde a aliquota é 25% e se for ver eles cobram Juros sobre os próprios juros dando quase uma aliquota de 32 % e não 25%.

espero ter te ajudado !!
OI Aqui é o Veio Modernel
Spitzer
Usuário Nível 2
Usuário Nível 2
Mensagens: 60
Registrado em: 15 Ago 2003 04:56
Localização: Nova Fátima - PR

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Spitzer »

Olá, Manuel!

Obrigado pela resposta.

Com regra de três não é possível (creio eu!).
Acontece que haverá casos (e é fato real isto, pois já houve casos assim) que eu posso ter um certo valor contratado que se ele fosse a base final para o RPA, não haveria a incidência de IR.
Se não me engano, o valor que passa a ter incidência de IR é R$ 1.372,81.
Então imagine um valor contratado de R$ 1.350,00.
Quando eu for achar um valor bruto que, com o descontos ele dê R$ 1.350,00, este bruto terá então incidência de IR.
Quer dizer, há casos onde a relação percentual do bruto para o líquido é de 15%, por exemplo, mas há casos onde esta relação é 17%, 19%...
Os descontos não possuem um percentual fixo. E há descontos que dependendo do valor, podem ou não ocorrer.

EU FIZ ASSIM:
Sobre o valor contratado, digamos os R$ 625,92, já acrescento 10%, pois em nenhuma hipóstese os descontos serão inferiores a isto.
Isto eleva o valor a R$ 688,51.
Então chamo a rotina de cálculo passando 688,51 como parâmetro e verifico o valor líquido retornado.
O valor líquido retornado será inferior a 625,92.
Então aumento 0,01 (1 centavo) e chamo a rotina de cálculo novamente, passando, desta vez, 688,52.
O valor retornado é ainda inferior a 625,92.
Aí chamo a rotina novamente passando 688,53, depois, 688,54, depois 688,55... Até que eu chamo a rotina passando 713,70 como parâmetro e o valor líquido retornado é 625,92, que é o valor contratado (a ser efetivamente pago).
Só que isto tá levando uma eternidade! Mais de meia hora!
Se eu não tivesse acesso a base de dados, fossem só cálculos simples, estas mais de 2.500 vezes que a rotina é chamada por tentativa e erro, levaria menos de 5 segundos.
Então tenho que reduzir o número de chamadas para 15, talvez 20 vezes, no máximo.
Agora, como faço isto já que não há uma regra fixa?
Pois há impostos que são cumulativos e a partir de um certo valor que começa a calcular, outros, que dependendo do valor, pegam faixas diferentes de percentuais de descontos (como o IR, por exemplo, que possui a isenção, 15% ou 27,5% de desconto, e que ainda, se o valor for inferior a R$ 10,00, não se desconta nem recolhe), e outros ainda, que quando atingem um determinado teto, não se desconta mais, como o INSS, por exemplo.

É um saco ou não?
Abraços,
Ademir Spitzer
MARINI
Usuário Nível 3
Usuário Nível 3
Mensagens: 288
Registrado em: 06 Jul 2004 08:06
Localização: Pindamonhangaba SP

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por MARINI »

Bom dia,
A fórmula é:

valor/((100-taxas)/100)
Sds
Marini
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por rochinha »

Amiguinho

Use a formula acima, carregue os valores de limite e teto antes de entrar no laco, tipo:

Código: Selecionar todos

// Puxe Varlores Da Tabela INSS conforme seus campos
INSS_Limite0 := 0
INSS_Limite1 := 50
INSS_Limite2 := 150
INSS_Limite3 := 300
INSS_Limite4 := 450
...
do case
    case ( ValorQueQueroTestar > INSS_Limite0 .and. ValorQueQueroTestar <= INSS_Limite1 )
    ...
    case ( ValorQueQueroTestar > INSS_Limite1 .and. ValorQueQueroTestar <= INSS_Limite2 )
    ...
    case ( ValorQueQueroTestar > INSS_Limite2 .and. ValorQueQueroTestar <= INSS_Limite3 )
    ...
endcase
Use este esquema para cada tabela que voce possue e coloque o laco para usar este método, os acesso as tabelas serão reduzidos a nada.

Eu usei estes métodos em meu antigo sistema de cooperativas que produzia num unico dia cerca de 3000 holerits com calculos complexos e a maioria dos calculos existiam na tabela de eventos onde eu armazenava para cada evento as variaveis e seus calculos como codeblocks que eram avaliados no momento do uso da rotina de calculo, exemplos:

Código: Selecionar todos

EVENTO | DESCRICAO | TRIBUTAVEL | CODEBLOCK
999 | PRODUCAO BASE | S | M->QTDE:=0,M->VALOR:=M->SALARIO*IIF(M->IDSALARIO=10,M->DIAS,1)
81 | HORA EXTRA 50% | S | IIF(M->VLEXTRAS=0,M->BASEHORA * 1.5,M->VLEXTRAS)
82 | HORA EXTRA 100% | S | IIF(M->VLEXTRAS=0,M->BASEHORA * 2,M->VLEXTRAS)
77 | COMISSAO | N | M->COMISSAO
122 | D.S.R.SOBRE COMISSOES | S | DIV(M->COMISSAO,M->DIAS-M->FOLGAS)*(M->FOLGAS-(M->FALTAS+M->FOLGAS))
Minha tabela de eventos possui mais de 100 eventos e cada funcionario seria verificado 100 vezes para o calculo dos eventos lancados em seu holerit. Para reduzir isto, o holerit do mesmo era avaliado a partir de alguns eventos selecionados e armazenados em uma tabela de eventos por funcionario, diminuindo o laco para cda calculo.

Em suma, antes de iniciar a rotina de calculos eu levava o maximo de informações para a memória para evitar aberturas e fechamentos de tabelas, pois se um delas se corrompesse no meio do caminho, tudo tinha de ser refeito. Na verdade a rotina fazia a impressão do holerit, então imagine o problema.

Não use a cabeça, use a memória, do micro.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por MARCELOG »

Veja isso:

VALOR BRUTO: 713,70
DESCONTOS: 3,57
INSS RETIDO: 15,70
ICMS – SUBSTITUIÇÃO: 68,51
VALOR LÍQUIDO: 625,92

x := 0
nValorLiq := 700,00
nBruto:=nValorLiq

Do while .t.

Crie as regras para cálculo dos impostos (com as classes de rendimento) considerando o valor líquido como o bruto incial, colocando o resultado na variável x.
Para agilizar o processo aumente o valor inicial com o mínimo exigível, e/ou crie faixas mínimas conhecidas.
Ex:

Se o valor é 1.000, não dá menos de 1.500
Então nBruto é

nBruto := nBruto *1,5

Isso retira 50.000 loops (R$500,00 : R$0,01)

Inss
Icms
Ir/Fonte
Descontos

Agora x é igual ao líquido, então é só comparar.

if x # (nValorLiq-0,01) or x # (nValorLiq+0,01) // Admito uma diferencinha.
nBruto + 0,01
Loop
else
exit
endif

enddo

? nBruto

MarceloG

Ou então, use o processo binário.
Água mole em pedra dura tanto bate que até espirra!
MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por MARCELOG »

Não falei do processo binário né.

Simples... (rsrsrsrs)

Pegue o valor, multiplique o mesmo por dois e teste.
Ex:
Se o líquido é igual a 700 faça o teste com 1.400,00

Se o resultado final líquido é maior que o líquido desejado, faça o teste loop retirando centavos.

Caso contrário, faça o teste loop acrescentando centavos.

Isso garante metade do tempo de processamento e pode ser refinado, comparando e dividindo/ multiplicando por dois as diferenças verificadas de modo a reduzir ainda mais esse tempo.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Manuel Luis Modernel
Usuário Nível 2
Usuário Nível 2
Mensagens: 66
Registrado em: 02 Mar 2008 20:40
Localização: São José do Rio Preto - SP

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Manuel Luis Modernel »

OI Amigo Spitzer,

Já foi levantado aqui um caso similar onde "O Programador" tentava resolver o problema "do Contador" e é isto que está acontecendo contigo no meu ver, teu problema não é de Programação e sim de Matematica Financeira.

A opinião geral foi nestes moldes:
VC enquanto PROGRAMADOR não tem obrigação de saber todas as rotinas administrativas de uma empresa, e por este motivo nada melhor do que consultar a pessoa que vem fazendo estes CÁLCULOS NO BRAÇO a muito tempo.
Te garanto que a pessoa deve ter uma saida muito simples e correta, caso contrário não teria feito por tanto tempo na "Maquininha de Calcular".

Perguntar a quem faz e sabe não é VERGONHA, quando a gente esta programando nada melhor do que colocar um pouco de responsabilidade no usuário, fazer ele participar, opinar e até testar o que VC está fazendo(lógico quando isto é possível). É assim que um programa fica 100% correto na opinião do usuário e é esta pessoa que vai fazer tua Propaganda posto que ele participou e ajudou a faze-lo.
OI Aqui é o Veio Modernel
Spitzer
Usuário Nível 2
Usuário Nível 2
Mensagens: 60
Registrado em: 15 Ago 2003 04:56
Localização: Nova Fátima - PR

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Spitzer »

CONSEGUI! CONSEGUI! CONSEGUI!

Na solução que vou postar abaixo, em todos os testes que fiz, a função foi chamada, no máximo, apenas 10 vezes!
O resultado sai em poucos segundos (10, 12... 15, foi o máximo, nos testes que fiz).

Faço assim:
O primeiro cálculo chamo pelo valor contratado (que é o líquido, digamos, 625.92), considerando que este seria o valor bruto, ou seja, a minha base de cálculo.
Aí, do valor líquido que deu (548.93), apuro a diferença para o que deveria dar (os tais 625.92).
A primeira diferença é de 76.99.
Somo esta diferença ao valor da minha primeira tentativa (625.92 + 76.99), que dá 702.91.
Então, para a minha próxima tentativa, a base de cálculo será os tais 702.91.
Esta base de cálculo gera um líquido de 616.46, que para o líquido que deveria dar (625.92), dá uma diferença de 9.46.
Aí somo a minha segunda base de cálculo à diferença (702.91 + 9.46), e chego ao valor de 712.37.
E assim sucessivamente, até que o líquido que deu (625.92) é o líquido que realmente deveria dar (625.92), e minha última base de cálculo, o meu valor bruto, que é os tais 713.7.

Na coluna "Líquido que Deu", é o líquido que peguei depois que a função faz os cálculos e me retorna o valor líquido. Se alguém quiser destrinchar pelos meus exemplos que postei antes, pode ver que chegará certinho nos valores que estão na citada coluna!

Depois desta, considero que minha semana foi muito bem ganha!

Abaixo, as apurações no Excel para entenderem melhor.

Lembrando que no segundo exemplo, no primeiro cálculo, não incide IRRF, mas a partir do segundo cálculo, sim.
E no terceiro exemplo, no meio do cálculo, a faixa muda no meio do cálculo (de 15 para 27,5%).

Pessoal, muito obrigado pelas dicas e sugestões!

As apurações:

Código: Selecionar todos

Bruto: 713,70    Líquido: 625,92
Quant.de       Base de      Líquido      Líquido que
Tentativas     Cálculo      que Deu      Deveria Dar    Díferença
         1      625,92       548,93           625,92        76,99
         2      702,91       616,46           625,92         9,46
         3      712,37       624,76           625,92         1,16
         4      713,53       625,76           625,92         0,16
         5      713,69       625,91           625,92         0,01
         6      713,70       625,92           625,92          -

Bruto: 4.000,00    Líquido: 3.469,77
Quant.de       Base de      Líquido      Líquido que
Tentativas     Cálculo      que Deu      Deveria Dar    Díferença
         1      3.469,77   3.042,99         3.469,77       426,78
         2      3.896,55   3.384,91         3.469,77        84,86
         3      3.981,41   3.454,51         3.469,77        15,26
         4      3.996,67   3.467,04         3.469,77         2,73
         5      3.999,40   3.469,27         3.469,77         0,50
         6      3.999,90   3.469,69         3.469,77         0,08
         7      3.999,98   3.469,75         3.469,77         0,02
         8      4.000,00   3.469,77         3.469,77          -

Bruto: 8.000,00    Líquido: 6.686,98
Quant.de       Base de      Líquido      Líquido que
Tentativas     Cálculo      que Deu      Deveria Dar    Díferença
         1      6.686,98   5.671,95         6.686,98     1.015,03
         2      7.702,01   6.456,63         6.686,98       230,35
         3      7.932,36   6.634,70         6.686,98        52,28
         4      7.984,64   6.675,10         6.686,98        11,88
         5      7.996,52   6.684,30         6.686,98         2,68
         6      7.999,20   6.686,36         6.686,98         0,62
         7      7.999,82   6.686,84         6.686,98         0,14
         8      7.999,96   6.686,95         6.686,98         0,03
         9      7.999,99   6.686,97         6.686,98         0,01
        10      8.000,00   6.686,98         6.686,98          -
Abraços,
Ademir Spitzer
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por rochinha »

Amiguinho,
Spitzer escreveu:Depois desta, considero que minha semana foi muito bem ganha!
Vou mandar o numero de minha conta para receber minha parte, então!!!

Boa sorte
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Manuel Luis Modernel
Usuário Nível 2
Usuário Nível 2
Mensagens: 66
Registrado em: 02 Mar 2008 20:40
Localização: São José do Rio Preto - SP

Re: Problema de Lógica - Meus Dois Neurônios Estão em Parafuso!

Mensagem por Manuel Luis Modernel »

O mestre Rochinha, eu só dei conselhos mais se a coisa tá assim eu tb gostaria de receber um troco hihihihii

gente este forum é excelente pelo nivel de compreensão e camaradagem dele, karacas demorei demias para encontar !!!

Uma Beijunda a todos do veio Modernel !!!
OI Aqui é o Veio Modernel
Responder