Página 1 de 1

MAPA DE TROCO

Enviado: 19 Mai 2021 07:52
por informais
Olá amigos, bom dia

Preciso fazer um Mapa de troco,

Exemplo

R$ 45,30
2 Nota(s) de R$ 20,00
4 Nota(s) de R$ 10,00
1 Nota(s) de R$ 5,00
3 Moedas de R$ 0,10

etc


Algo mais ou menos assim

MAPA DE TROCO

Enviado: 20 Mai 2021 09:55
por JoséQuintas
informais escreveu:R$ 45,30
2 Nota(s) de R$ 20,00
4 Nota(s) de R$ 10,00
1 Nota(s) de R$ 5,00
3 Moedas de R$ 0,10
também poderia ser 1 moeda de 0.25 e 1 de 0,05
Ou 3 reais de troco, poderiam ser 3 moedas de 1, ou 1 nota de 2 + 1 moeda de 1

É fazer a tabela de notas/moedas.
Vai usar Int() e Mod().

MAPA DE TROCO

Enviado: 20 Mai 2021 10:22
por JoséQuintas

Código: Selecionar todos

PROCEDURE Main

   LOCAL nValor := 45.30
   LOCAL aItem

   FOR EACH aItem IN Troco( nValor )
      ? Str( aItem[ 1 ], 3 ) + " " + aItem[ 2 ] + " de " + Str( aItem[ 3 ] )
   NEXT
   Inkey(0)

   RETURN

FUNCTION Troco( nValor )

   LOCAL aList := { ;
      { 50, "nota(s)" }, ;
      { 20, "nota(s)" }, ;
      { 10, "nota(s)" }, ;
      { 5, "nota(s)" }, ;
      { 2, "nota(s)" }, ;
      { 1, "moeda(s)" }, ;
      { 0.50, "moeda(s)" }, ;
      { 0.25, "moeda(s)" }, ;
      { 0.10, "moeda(s)" }, ;
      { 0.05, "moeda(s)" }, ;
      { 0.01, "moeda(s)" } }
   LOCAL aTroco := {}
   LOCAL aItem, nQtd

   FOR EACH aItem IN aList
     nQtd := Int( nValor / aItem[ 1 ] )
     ? nValor, aItem[ 1 ], nQtd
     IF nValor >= aItem[ 1 ]
        nValor := nValor - ( nQtd * aItem[ 1 ] )
        AAdd( aTroco, { nQtd, aItem[ 2 ], aItem[ 1 ] } )
     ENDIF
   NEXT

   RETURN aTroco
moeda.png
O problema é o Harbour fazer conta errada.

0.05 / 0.05 deu zero
e 0.05 / 0.01 deu 4

MAPA DE TROCO

Enviado: 20 Mai 2021 10:37
por JoséQuintas

Código: Selecionar todos

PROCEDURE Main

   LOCAL nValor := 45.30
   LOCAL nItem

   FOR EACH nItem IN Troco( nValor )
      ? Str( nItem[ 1 ], 2 ) + " " + iif( nItem[ 1 ] < 2, "moeda(s)", "nota(s)" ) + " de " + Str( nItem[ 2 ] )
   NEXT
   Inkey(0)

   RETURN

FUNCTION Troco( nValor )

   LOCAL aList := { 50, 20, 10, 5, 2, 1, 0.50, 0.25, 0.10, 0.05, 0.01 }
   LOCAL aTroco := {}
   LOCAL nItem, nQtd

   nValor := Int( nValor * 100 )
   FOR EACH nItem IN aList
     nQtd := Int( nValor / ( nItem * 100 ) )
     //? nValor/100, nItem, nQtd
     IF nValor >= ( nItem * 100 )
        nValor := nValor - ( nQtd * nItem * 100 )
        AAdd( aTroco, { nQtd, nItem } )
     ENDIF
   NEXT

   RETURN aTroco
moeda.png
moeda.png (10.61 KiB) Exibido 2437 vezes
Mais simples, considerando que abaixo de 2 reais é moeda
E trabalhando com valor multiplicado por 100, pra evitar erro de cálculo.

MAPA DE TROCO

Enviado: 20 Mai 2021 10:40
por JoséQuintas
Aproveitando...

Pra quem nunca viu erro de cálculo por causa do tal ponto flutuante, está aí.
Internamente 0.05 virou algo como 0.049999999999999999999999999999
Numa visão normal, tudo bem, mas em cálculos detalhados.... erro de cálculo.

MAPA DE TROCO

Enviado: 20 Mai 2021 10:47
por JoséQuintas
Pequena correção no fonte:

Código: Selecionar todos

 iif( nItem[ 2 ] < 2, "moeda(s)", "nota(s)" ) 
Ao invés de comparar o valor, eu tinha comparado a quantidade.

MAPA DE TROCO

Enviado: 20 Mai 2021 10:57
por Fernando queiroz
O único problema é saber o tipo e a quantidade do troco, ou tal mapa é somente para informacao?????
caso não seja somente para informação tem de carregar os tipos de notas e moedas, como acontece em caixa eletrônico, que você informa a quantidade de notas, valor e qual cassete ela esta localizada.
no caso de caixa eletronico tem somente dispenser e o recebimento é separado.

Quando trabalhei em Banco , dava manutenção em sistema de caixa eletrônico, era bem legal, tratar o hardware para contar e recusar notas com defeito

MAPA DE TROCO

Enviado: 20 Mai 2021 11:01
por JoséQuintas
Não prestei atenção sobre o tópico ser Clipper.
Troque o FOR/EACH por FOR nCont = 1 TO n, e acrescente uma linha.

Código: Selecionar todos

FOR EACH nItem IN a List
troque por

Código: Selecionar todos

FOR nCont = 1 TO Len( aList )
   aItem := aList[ nCont ]
E ao invés de usar direto o Troco( nValor ) no FOR/EACH, primeiro atribua a uma variável.

Código: Selecionar todos

   FOR EACH nItem IN Troco( nValor )
troque por

Código: Selecionar todos

aList := Troco( nValor )
FOR nCont = 1 TO Len( aList )
   nItem := aList[ nCont ]
Assim o resto do fonte permanece igual.

MAPA DE TROCO

Enviado: 20 Mai 2021 11:44
por JoséQuintas
troco.png
Uia... sem erro de ponto flutuante no MySQL.

https://pctoledo.org/forum/viewto ... 26&start=0