Dodawanie ułamków "zwykłych"

Pytania, kody i porady dotyczące nie tylko Bascom.
ODPOWIEDZ
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 11 gru 2019, 21:59

Witam !
Bawię się dodając ułamki "zwykłe".
  1. 'dodawanie ułamków 11.12.2019
  2. $sim
  3. $regfile "m8def.dat"
  4. $crystal = 8000000
  5. $hwstack = 50
  6. $swstack = 50
  7. $framesize = 100
  8.  
  9. Config Lcd = 16 * 2
  10. Config Lcdpin = Pin , Rs = Pc.5 , E = Pc.4 , Db4 = Pc.3 , Db5 = Pc.2 , Db6 = Pc.1 , Db7 = Pc.0
  11. Cursor Off
  12. Cls
  13.  
  14. Dim L_1 As Byte
  15. Dim L_2 As Byte
  16. Dim L_3 As Byte
  17. Dim M_1 As Byte
  18. Dim M_2 As Byte
  19. Dim M_3 As Byte
  20. ' licznik_1            + licznik_1                 licznik_3
  21. 'mianowni_1       +mianownik_2        = mianownik_3
  22. L_1 = 2
  23. M_1 = 4
  24. L_2 = 4
  25. M_2 = 5
  26. L_3 = 0
  27. M_3 = 0
  28.  
  29. M_3 = M_1 * M_2
  30. L_3 = L_1 + L_2
  31.  
  32. Locate 1 , 1
  33. Lcd L_1 ; " +"
  34.  
  35. Locate 1 , 5
  36. Lcd L_2
  37.  
  38. Locate 1 , 9
  39. Lcd L_3
  40.  
  41. Locate 2 , 1
  42. Lcd M_1 ; " *"
  43.  
  44. Locate 2 , 5
  45. Lcd M_2
  46.  
  47. Locate 2 , 8
  48. Lcd M_3 ; "          "
  49.  
Po dodaniu 2/4 do 4/5 otrzymałem wynik 6/20.
Jak ułożyć program by był uniwersalny i skracał inne ułamki np. 7/21 itp. ?
Czy w Bascomie da radę taki program napisać ?
Założenia:
Bascom AVR DEMO ( max 4kB ) LCD 2x16, może kiedyś klawiatura 12to polowa.

Pozdrawiam. Stefan
ps. Dodawanie ułamków zwykłych KL 5 SP.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dodawanie ułamków "zwykłych"

Post autor: niveasoft » 11 gru 2019, 23:39

Jest trochę późno i głowa już nie ta więc błąd mógł się wkraść niemniej wychodzi na to że działa. Potestuj ;)
Nie żałujesz, że ktoś rozwiązał krzyżówkę za Ciebie? :P
  1. 'dodawanie ułamków 11.12.2019
  2. $regfile = "m8def.dat"
  3. $crystal = 16000000
  4. $hwstack = 64
  5. $swstack = 16
  6. $framesize = 64
  7. $baud = 19200
  8.  $sim
  9.  
  10. Config Submode = New                                        'konfiguruje Bascom. Najpierw piszesz funkcje i sub`y a dopiero potem kod i uzywasz funkcji
  11.  
  12.     Config Lcd = 16x2
  13.     Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
  14.     Cursor Off
  15.     Cls
  16.  
  17.     Dim L_1 As Byte , L_2 As Byte , M_1 As Byte , M_2 As Byte
  18.     Dim Temp1 As Byte , Temp2 As Byte , Temp3 As Byte       'zmienne pomocnicze
  19.     Dim Ll_1 As Byte , Ll_2 As Byte , Mm_1 As Byte , Mm_2 As Byte
  20.  
  21.     L_1 = 2                                                 'licznik
  22.     M_1 = 4                                                 'mianownik
  23.     L_2 = 4                                                 'licznik
  24.     M_2 = 5                                                 'mianownik
  25.  
  26. '----[ sub skraca ułamek jeśli to mozliwe]--------
  27. Sub Skracaj(byval Licz As Byte , Byval Mian As Byte)
  28.  
  29.   Print "Skracam " ; Licz ; "/" ; Mian
  30.  
  31.   Temp1 = Licz : Temp2 = Mian                               'zapamiętaj wprowadzone dane na wypadek gdyby nie udało się skrócić to będzie wynik
  32.  
  33.   If Licz > Mian Then                                       'jeśli licznik większy niz mianownik np.21/7
  34.    Temp3 = Licz Mod Mian                                    'sprawdź czy jak podzielimy L/M czy zostanie reszta
  35.    If Temp3 = 0 Then                                        'tylko jeśli nie ma reszty to możemy podzielic
  36.     Temp1 = Licz / Mian                                     'to nowy Licznik                                   '
  37.     Temp2 = 1                                               'to nowy mianownik
  38.    End If
  39.   Else                                                      'jeśli jednak mianownik większy od licznika np 7/21
  40.    Temp3 = Mian Mod Licz                                    'sprawdź czy jak podzielimy M/L czy zostanie reszta
  41.    If Temp3 = 0 Then                                        'tylko jeśli nie ma reszty to możemy podzielic
  42.     Temp1 = 1                                               'to nowy Licznik
  43.     Temp2 = Mian / Licz                                     'to nowy mianownik
  44.    End If
  45.   End If
  46.  
  47.   Print "Wynik skracania to " ; Temp1 ; "/" ; Temp2
  48.  
  49. End Sub
  50. '---------------------------------------------------
  51.  
  52. 'skracanie wstepne
  53. Call Skracaj(l_1 , M_1)                                     'wysyłamy ułamek do skrócenia podając licznik i mianownik
  54.  Ll_1 = Temp1 : Mm_1 = Temp2                                'wyniki sa w zmiennych Temp1 i Temp2
  55. Call Skracaj(l_2 , M_2)
  56.  Ll_2 = Temp1 : Mm_2 = Temp2
  57.  
  58. If Mm_1 <> Mm_2 Then                                        'jeśli mianowniki się różnią
  59.    Temp1 = Ll_1 * Mm_2                                      'mnozymy liczniki na krzyż
  60.    Temp2 = Ll_2 * Mm_1
  61.    Temp1 = Temp1 + Temp2                                    'dodawanie liczników
  62.    Temp2 = Mm_1 * Mm_2                                      'policz mianownik
  63. Else                                                        'lub jeśli mianowniki są już równe
  64.    Temp1 = Ll_1 + Ll_2                                      'dodaj tylko liczniki
  65.    Temp2 = Mm_1                                             'przepisz mianowniki
  66. End If
  67.  
  68. Call Skracaj(temp1 , Temp2)                                 'ostatecznie skróć nowy ułamek
  69.  
  70. Print ""
  71. Print "Wynikiem dodawania " ; L_2 ; "/" ; M_2 ; " do " ; L_1 ; "/" ; M_1 ; " jest " ; Temp1 ; "/" ; Temp2
  72.  
  73.  
  74. End
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Re: Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 12 gru 2019, 8:47

Witam !
DZIĘKUJĘ
Oczywiście że żałuję, że sam do rozwiązania nie doszedłem.
Na szybko widzę że wynik dodawania 2/4 i 4/5 jest zły, jest 13/10, a powinien być 3/10.

Teraz muszę zapoznać się z nieznajomymi dla mnie całymi liniami programu, np. ta:
Sub Skracaj(byval Licz As Byte , Byval Mian As Byte)
Sub - podprogram ( domyślam się ), ale to:
byval ? określenie zakresy zmiennej ? jeśli tak to jaki zakres ?

Zastanawiam się dlaczego zaczynasz od skracania ułamków przed dodawaniem.

Dzisiaj postaram się poznać zasadę działania programu, co kolejna linia wykonuje, to dla mnie najważniejsze.
Dziękuję.
Bardzo proszę nie dawaj całych rozwiązań, wystarczy nakierowanie.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dodawanie ułamków "zwykłych"

Post autor: niveasoft » 12 gru 2019, 8:56

Kolego przyjrzyj się moim obliczeniom "na piechotę" bez wstępnego skracania. Coś mi się wydaje że ktoś z nas nie odrobił lekcji :D
Nie przesądzam sprawy. Pokaż jak to liczysz :P

Wstępne skracanie to po to by nie mnożyć dużych liczb. Ogólnie kod jest ograniczony do wartości które zmieszczą się w bajcie czyli do 255

O Byval i Byref napisałem tutaj -> viewtopic.php?f=16&t=168

Na początku napisałem wersję Byref, która operowała bezpośrednio na podanych danych i byłaby bardziej optymalna, ale potem na końcu nie mogłem napisać co było do czego dodawane i tylko dlatego przerobiłem na Byval
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Re: Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 12 gru 2019, 11:07

Masz rację, ale mnie zaćmiło !
Przecież pół i prawie całość 4/5 nie może być mniejsze od 1.
A z wnukiem robiłem to tak:
a/b+c/d
mnożyłem mianowniki, potem mnożyłem na krzyż a X d, b X c, potem już oba liczniki dodałem
2/4+4/5= 2x5+4x4 = 26- licznik =
4x5=20 - mianownik
Teraz sią zgadza 26/20=13/10

Wstępne skracanie to po to by nie mnożyć dużych liczb. Ogólnie kod jest ograniczony do wartości które zmieszczą się w bajcie czyli do 255---------ok, rozumiem.
To: Byval i Byref napisałem tutaj -> viewtopic.php?f=16&t=168 popatrzę trochę później, ze spokojem.

Możesz mi oczywiście postawić jedynkę za dodawanie ułamków zwykłych, chyba za szybko chciałem napisać działający program !
Ja się poprawię.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dodawanie ułamków "zwykłych"

Post autor: niveasoft » 12 gru 2019, 11:23

W takim razie dodałem do kodu więcej komentarzy.
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Re: Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 12 gru 2019, 12:40

SUPER, przydadzą się, DZIĘKUJĘ

Do Twojego programu doałem:
  1. Dim temp4 as byte
  2.  
  3. If Temp1 > Temp2 Then
  4. Temp4 = Temp1 / Temp2
  5. Temp1 = Temp1 Mod 10
  6. End If
  7. Print Temp4 ; "  " ; Temp1 ; "/" ; Temp2
  8.  
Chciałbym zamienić ułamek 13/10 na 1 i 3/10 to działa, ale jak zamieniam 27/9 to już tak pięknie nie jest.
Proszę, na razie nie podpowiadaj.

Już mam poprawiony program dział też z ułamkami nieskracalnymi np. 3/4, maksymalna wartość licznika lub mianownika 255 ( Byte )
  1. 'skracanie ułamka 13.12.2019
  2. $regfile = "m8def.dat"
  3. $crystal = 16000000
  4. $hwstack = 64
  5. $swstack = 16
  6. $framesize = 64
  7. $baud = 19200
  8. $sim
  9. Dim Temp1 As Byte , Temp2 As Byte , Temp3 As Byte , Temp4 As Byte
  10.  
  11. Temp1 = 255
  12. Temp2 = 5
  13. Print Temp1 ; "/" ; Temp2
  14.  
  15. If Temp1 > Temp2 Then
  16.    Temp3 = Temp1 / Temp2
  17.    Temp4 = Temp2 * Temp3
  18.    Temp4 = Temp1 - Temp4
  19.  
  20.       If Temp2 < 10 Then
  21.       Temp2 = Temp2 Mod 10                                  ' dla mianwnika do 9
  22.       Elseif Temp2 < 100 Then
  23.       Temp2 = Temp2 Mod 100                                 ' dla mianownika do 99
  24.       Elseif Temp2 < 200 Then
  25.       Temp2 = Temp2 Mod 1000                                ' dla mianownika większego
  26.       End If
  27. Else
  28.    Temp4 = Temp1
  29. End If
  30.  
  31. Print Temp3 ; " i " ; Temp4 ; "/" ; Temp2
  32. End
Ostatnio zmieniony 13 gru 2019, 12:02 przez sp3ots, łącznie zmieniany 1 raz.
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Re: Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 13 gru 2019, 11:40

Wczoraj nic nie wymyśliłem, ale dzisiaj napisałem to:
  1. 'skracanie ułamka 13.12.2019
  2. $regfile = "m8def.dat"
  3. $crystal = 16000000
  4. $hwstack = 64
  5. $swstack = 16
  6. $framesize = 64
  7. $baud = 19200
  8. $sim
  9. Dim Temp1 As Byte , Temp2 As Byte , Temp3 As Byte , Temp4 As Byte
  10.  
  11. Temp1 = 25
  12. Temp2 = 13
  13. Print Temp1 ; "/" ; Temp2
  14.  
  15. If Temp1 > Temp2 Then
  16.    Temp3 = Temp1 / Temp2
  17.    Temp4 = Temp2 * Temp3
  18.    Temp4 = Temp1 - Temp4
  19.  
  20.       If Temp2 > 9 Then
  21.       Temp2 = Temp2 Mod 100                                 ' dla mianwnika większego od 9
  22.       Else
  23.       Temp2 = Temp2 Mod 10                                  ' dla mianownika do 9
  24.       End If
  25.  
  26. End If
  27. Print Temp3 ; " i " ; Temp4 ; "/" ; Temp2ownik
  28. End
  29.  
Problem występuje gdy wpiszę ułamek nieskracalny, wtedy jest zły wynik.
Jeśli wpiszę taki ułamek:
Temp1 = 250- licznik
Temp2 = 130- mianownik
to mianownik mam obcięty z lewej strony, ale to wiem jak poprawić.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Dodawanie ułamków "zwykłych"

Post autor: niveasoft » 13 gru 2019, 17:38

Coś tam Pan chyba śpi.
Jak można napisać "Temp2 = Temp2 Mod 1000" jak Temp2 to Byte który ma maks 255?
Mod to reszta z dzielenia i prosiłbym by poczytał Pan Helpa do danej instrukcji.

Proszę o inny zestaw pytań :D

Co do zamiany 13/10 na 1 i 3/10 to proste
Piszę warunek If Licznik > Mianownik Then ...

Liczba_całkowita = Licznik / Mianownik
Nowy_licznik = Licznik Mod Mianownik

Przepraszam jeśli się gdzieś pomylę, ja to pisze z głowy... a jest piątek ;)
sp3ots
Posty: 42
Rejestracja: 08 wrz 2018, 10:26

Re: Dodawanie ułamków "zwykłych"

Post autor: sp3ots » 13 gru 2019, 19:44

"Co do zamiany 13/10 na 1 i 3/10 to proste
Piszę warunek If Licznik > Mianownik Then"

To już mam zrobione w drugim kodzie.

"Temp2 = Temp2 Mod 1000"

Wiem że byte jest do 255,
"Temp2 = Temp2 Mod 1000" nie zgłasza błędu, tak zostawię.
Zamiast byte można dać long, integer, w tej chwil to nie jest problem.

Przyszłość to dodanie LCD 2x16, potem klawiatura matrycowa.
ODPOWIEDZ