DISTRIBUI?ÃO DE DESCONTO NOS ITEMS

FBGSYSTEMS 16/07/2015 17:59:24
#448936
Bom dia pessoal.
Estou com um problema para distribuir desconto dado no total do orçamento/nota pelos itens
Vez bate certinho, e vez não.

Eu pego o total da nota vejo o percentual do desconto e distribuo no valor total de cada item. Mas nem sempre da certo. As vezes a diferença é de até 0,05 R$.

Como voces fazem para que isto nao ocorra ?



Segue meu codigo para distribuição do desconto.

         varDescontoPor = Format((CDbl(txtDescontoTotal) * 100 / CDbl(lblTotal)), [Ô]#####,##0.00[Ô])
Set dspoedesconto = New ADODB.Recordset
dspoedesconto.Open [Ô]select * from detorcamentos where codorc=[Ô] & cmbOrc, con, adOpenDynamic, adLockOptimistic
Do While Not dspoedesconto.EOF
varValorDescontoItem = Format(Truncar((dspoedesconto!valor * dspoedesconto!Qtd) * varDescontoPor / 100, 2), [Ô]####,###0.00[Ô])
[ô]varValorDescontoItem = Format((dspoedesconto!valor) * varDescontoPor / 100, [Ô]####,###0.00[Ô])
[ô]dspoedesconto!Desconto = varValorDescontoItem * dspoedesconto!Qtd
dspoedesconto!Desconto = varValorDescontoItem
dspoedesconto.Update
dspoedesconto.MoveNext
Loop
KERPLUNK 16/07/2015 18:40:09
#448938
A questão aqui é matemática. Simplesmente não vai fechar nunca justamente por ser percentual. Veja o caso:
25% de 100 é 25 ou seja, 100 = 25% * 4
25% de 25 é 6,25, ou seja, 100 = 25% de (25% de 100)

Nesse caso a conta vai fechar, pois 6,25 * 16 = 100, mas quando os valores percentuais mudam esses números serão muito diferentes e por isso sua soma não vai fechar nunca. Tinha um professor que me contava uma estória sobre isso, acompanhe:
Você e mais dois amigos foram à um bar e beberam algo. A conta da mesa deu 25 reais. Cada um pegou uma nota de 10 reais e deu para o garçom que prontamente foi ao caixa, pagou os 25 e voltou com 5 moedas de um real. Vocês três resolveram deixar 2 reais de gorjeta pro garçom e pegaram cada um uma das 3 moedas que sobraram do troco. Então é como se cada um tivesse pago apenas 9 reais e não 10. Então se somar (3 * 9) + 2, ou seja, os 9 reais de cada um mais os dois da gorjeta do garçom, você vai ter o resultado de 29 e não de 30 que foi o montante de dinheiro envolvido. Agora tente entender porque a conta não fecha...
ASHKATCHUP 16/07/2015 18:55:31
#448939
A conta não fecha porque não tem como dividir 5 moedas de R$1,00 igualmente entre três pessoas.



KERPLUNK 16/07/2015 19:29:38
#448940
Citação:

:A conta não fecha porque não tem como dividir 5 moedas de R$1,00 igualmente entre três pessoas.


Não, não é isso. As moedas não foram divididas 5 por 3. Pegaram 2 das e deram ao garçom e ficaram com 1 cada um. A conta não fecha mas não é por isso... Pense bem...
JABA 16/07/2015 19:54:04
#448942
Kerplunk, a conta não fecha porque está se distribuindo 5 reais em cima de 30 novamente, e isso não poderia acontecer porque se já foram retirados 5 reais, não poderia existir a possibilidade de retornar 1 real em cima dos 10 de cada um (10 de cada um dá 30), pois senão estaríamos usando 5 reais (extras) para redistribuir sobre os 30. Ou seja, se 5 moedas de 1 real estão com o garçom, o certo seria retornar 3 reais (ficando 2 de gorjeta) em cima de 25 reais, não dos 30 novamente.

O que está acontecendo é mais ou menos assim:

Citação:

5 reais está com o garçom (Esse é um dinheiro que foi colocado na estória de forma a causar o erro matemático.)



Citação:

Esses são os valores usados quando se volta 1 real na estória:
10 com Fulano1
10 com Fulano2
10 com Fulano3



Citação:

Veja que somando tudo acima da 35 e não 30, o que não poderia acontecer, mas é isso que acontece na sua estória. Daí na distribuição fica assim:

Volta 1 real dos 5 reais que está com o garçom;

Agora o garçom fica com 4 reais em mãos
09 com Fulano1
10 com Fulano2
10 com Fulano3

Volta 1 de troco

Agora o garçom fica com 3 reais em mãos
09 com Fulano1
09 com Fulano2
10 com Fulano3

Volta 1 de troco

Agora o garçom fica com 2 reais em mãos. (Aqueles que foram dados de gorjeta)
09 com Fulano1
09 com Fulano2
09 com Fulano3

Daí 09+09+09+02 = 29



Citação:

O erro aí é na estória, não no cálculo matemático. Ou seja, isso aí é uma pegadinha.



Citação:

Se você não entendeu, pergunte-se como poderia 5 reais (dinheiro que foi retirado dos 30, mas na história ele está sendo incrementado aos 30) serem redistribuídos em cima dos 30 reais novamente, que vai ficar mais claro o entendimento.


KERPLUNK 16/07/2015 20:13:49
#448943
JABA, não, também não é bem isso. Leia bem a estória, é uma situação perfeitamente possível de acontecer, o único erro é a aplicação da matemática nela. Vou explicar:
A conta deu 25 reais. Cada um deu 10 reais. O caixa pegou as 3 notas de 10(30 reais) e devolveu o troco de 5 reais em 5 moedas de um. O garçom ficou com 2 das 5 moedas e devolveu as 3 moedas restantes, que foram divididas entre os 3, ou seja, 1 real para cada um. Na estória eu digo que é o mesmo que cada um ter pago 9 reais, certo? Pois é, mas não é assim que se deve ver. Na matemática, temos ordem de sinais, ou seja, as operações devem ser executadas em uma ordem e por isso não se pode dizer que cada um pagou 9 simplesmente porque depois da operação de pagamento cada um recebeu 1 de volta. Matematicamente falando a conta é:
((10 + 10 + 10) - 25) - 2 = 3

Mas na estória estamos fazendo diferente:
30 - ((9 + 9 + 9) + 2) = 1

Em resumo, você não pode fazer as operações na ordem errada ou o resultado vai mudar. Por isso que o FGBSYSTEMS está tendo problemas. Ele tem um total e quer aplicar desconto percentual no total e dividir isso pelos fatores(ítens) e a ordem não é essa. Essa é a razão de ele estar tendo problemas e os números nem sempre batem. Ou seja, o problema não é o código, é a matemática.
JABA 16/07/2015 20:16:35
#448944
Kerplunk, eu dei um reeditada no que tinha postado. Veja aí novamente e me diga se não é o que eu estou dizendo. Não é por nada não, mas essa aí eu tenho certeza absoluta.
KERPLUNK 16/07/2015 20:23:21
#448945
JABA, era isso mesmo, você estava certo, acho que eu é que não entendi direito o modo como explicou, mesmo estando certo. Enfim, é esse o problema do FGBSYSTEM
JABA 16/07/2015 20:29:35
#448946
Esse problema é bem antigo. Se a pessoa se concentrar na estória, nunca vai acertar, porque são acrescentados coisas que não é muito fácil detectar. Pra resolver isso, é preciso concentrar-se apenas nos números e esquecer o que se passa no desenrolar da estória. Existem muitas outras parecidas com essa, tipo uma que o cara entra com uma menor quantia e dividi o que tem com os irmãos, e no final todo mundo sai com dinheiro a mais.
FBGSYSTEMS 16/07/2015 20:51:29
#448948
Kerplunk, ja havia visto essa historia mas nao sabia a resoluçao.
Mas ainda nao consegui identificar como resolvo meu problema.

Para o cliente, eu mostrei como estava sendo feito. .ele tb nao conseguiu identificar como resolver. Entao logo deduzi que o problema era matematica e nao logica de programaçao.
Vou bater cabeça aqui com base nisso q vc falou..se eu conseguir aviso aqui. Apesar do receio em ter conhecimento matematico o suficiente.
JABA 16/07/2015 21:02:36
#448950
FBGSYSTEMS, eu creio que o seu problema está no arredondamento. Por exemplo, se certo valor estiver 0,6, o vb arredonda pra 1,0. Faça o teste com mais casais decimais e veja se vai. Ou isso está acontecendo no [Ô]Format[Ô], no [Ô]Truncar[Ô] ou no [Ô]Cdbl[Ô]. Provavelmente é na função [Ô]Truncar[Ô]

Ponha os valores que estão ficando errados aqui pra gente poder fazer os cálculos em cima deles.
Página 1 de 3 [21 registro(s)]
Tópico encerrado , respostas não são mais permitidas