Posty bez odpowiedzi |oraz Aktywne tematy Dzisiaj jest 2024-12-18, 04:09x



Odpowiedz w temacie  [ Posty: 8 ] 
Symfonia błędnie oblicza działania matematyczne 
Autor Wiadomość

Rejestracja: 2008-06-03, 12:18
Posty: 106
Post Symfonia błędnie oblicza działania matematyczne
Zaintrygowała mnie pewna sprawa w Symfonii Handel 2006c

Piszę raport, gdzie potrzebuję się dowiedzieć, czy wynik dzielenia jest całkowity czy ułamkowy.
Rozwiązuje to reszta z dzielenia, czyli operator %.
Jednak gdy podam liczby zmiennoprzecinkowe (float) to wywala błąd, więc rozumiem, że operator pracuje na liczbach całkowitych.

Więc zabieram się do ominięcia operatora, korzystając z funkcji zaokrąglającej Round.

Oto przykład, gdzie mam błąd:

Kod:

float liczba1 = 4.2
float liczba2 = 1.4
float wynik = liczba1/liczba2
FLOAT rwynik = Round(wynik,0)
if  (wynik-rwynik)==0 then
   Message "Brak reszty - OK"
else
   Message "Jest reszta"
endif
Error ""


Komunikat, który mi wyskakuje to "Jest reszta". Gdy liczby są całkowite działa to prawidłowo, jeśli zmiennoprzecinkowe to też działa, ale ten przykład akurat NIE!!
Załamać się idzie.
Zmienna wynik w powyższym przykładzie wyniesie 3.0, zaokrąglony całkowitej jako zmienna też wyniesie 3. Więc 3-3 jest 0 i powinno się pokazać "Brak reszty". Jak dam liczby np. 5.6 i 1.4 to wynikiem będzie całe 4 i pokazuje dobrze. Jak dam 3.9 i 1.3 to też jest dobrze.

ZNALAZŁEM drugi przypadek. To para liczb 3.3 i 1.1

Proszę wklejcie ten krótki raport do Symfonii i przekażcie wyniki, bo się idzie pochlastać.

Dziękuję z góry

Zamiast if..endif dałem select case..end select - niestety to samo w przypadku tych dwóch par liczb. Być może jeszcze jakieś istnieją :(

Kod:

Select Case (wynik-rwynik)
   Case 0
      Message "Brak reszty - OK"
   Case Else
      Message "Jest reszta"
EndSelect



2009-03-16, 16:13
Wyświetl profil
Autor Wiadomość
 


Ekspert
Ekspert

Rejestracja: 2007-11-16, 15:08
Posty: 4004
Pomógł: 448
Post 
Kod:
int Sub CzyJestReszta(dloat liczba1, float liczba2)

   int temp   
   wynik = liczba1 / liczba2

   if temp != wynik then CzyJestReszta = 1

endsub


funkcja zwraca 1 jeżeli jest reszta

_________________
Skontaktuj się z Ekspertem | Zamów dodatek

tel. 22 7 538 538
ekspert@mojaSymfonia.pl
http://www.mojaSymfonia.pl


2009-03-16, 16:37
Wyświetl profil
Ekspert
Ekspert
Awatar użytkownika

Rejestracja: 2008-04-18, 18:52
Posty: 5169
Pomógł: 59
Post 
Moze warto na wykładach o systemie binarnym czasem sluchac prowadzacego jak mowi o reprezentacji ulamkow dziesietnych w systemie binarnym

dla przykładu 1.4 (dec) to 1.0110(0110)(bin) czyli ulamek okresowy wiec nie jest dokładnie zapisywane jako 1.4 w kompie

zreszta 0.3 ma podobne rozwiniecie co prawda nie okresowe ale za to dość długie

stad moze i handel zle liczy bo procedury na liczbach float zawsze maja takie problemy

stad przy pisaniu takich funkcji dobra praktyka jest zaokraglać

if (round(wynik,2)-round(rwynik,2))==0 then

wiecej na ten temat tutaj:

http://support.microsoft.com/kb/78113/pl


PS a funkcja rafala nie dziala - bo chyba temp nigdzie nie jest w niej obliczany :(


2009-03-16, 17:10
Wyświetl profil

Rejestracja: 2008-06-03, 12:18
Posty: 106
Post 
Dziękuje rafal, ale chyba funkcja jest niepełna. Co przedstawia zmienna temp??
Przyznacie, że w moim kodzie powinno być OK, skoro dla szeregu innych parametrów jest dobrze to dlaczego nie jest w przypadku pary 4.2, 1.4 i 3.3 i 1.1?


2009-03-16, 17:14
Wyświetl profil
Ekspert
Ekspert

Rejestracja: 2007-11-16, 15:08
Posty: 4004
Pomógł: 448
Post 
Kod:
int Sub CzyJestReszta(float liczba1, float liczba2)

    int temp   
    float wynik = liczba1 / liczba2
    temp = wynik
    if temp != wynik then CzyJestReszta = 1

endsub

temp jest typu int.

po przypisaniu wyniku dzielenia do temp w tempie przechowywana jest część całkowita wyniku dzielenia.

Błędem jest uzycie Rounda bo to zaokragla a nie obcina część dziesiętną.[/code]

_________________
Skontaktuj się z Ekspertem | Zamów dodatek

tel. 22 7 538 538
ekspert@mojaSymfonia.pl
http://www.mojaSymfonia.pl


Ostatnio zmieniony 2009-03-17, 09:39 przez rafal, łącznie zmieniany 2 razy



2009-03-16, 17:18
Wyświetl profil

Rejestracja: 2008-06-03, 12:18
Posty: 106
Post 
Masz rację wrob. Próbowałem w Delphi tego samego przykładu i..... to samo. Też uznał, że wyniki tych obliczeń dla 4.2 i 1.4 są różne - czyli jest reszta, choć jej nie ma.

Problem rozwiązałem mnożąc argumenty przez 10, gdyż nie będą to liczby po przecinku więcej jak 1. Ciekawa sprawa

Jeszcze raz dziękuję Panowie.

Pozdrawiam.


2009-03-16, 17:34
Wyświetl profil
Ekspert
Ekspert

Rejestracja: 2007-11-16, 15:08
Posty: 4004
Pomógł: 448
Post 
kolejne próby :

Kod:
int Sub CzyJestReszta(float liczba1, float liczba2)

    float fwynik = liczba1 / liczba2
    int itemp = fwynik: float ftemp = fwynik
    if ftemp != fwynik then    
      CzyJestReszta = 1
   else
      CzyJestReszta = 0
   endif

endsub

_________________
Skontaktuj się z Ekspertem | Zamów dodatek

tel. 22 7 538 538
ekspert@mojaSymfonia.pl
http://www.mojaSymfonia.pl


Ostatnio zmieniony 2009-03-17, 09:38 przez rafal, łącznie zmieniany 2 razy



2009-03-16, 18:05
Wyświetl profil

Rejestracja: 2009-02-12, 16:21
Posty: 46
Post 
Benji_Pete pisze:
Przyznacie, że w moim kodzie powinno być OK


Nie jest przykład OK. To są liczmy zmienno przecinkowe a one rządzą się swoimi prawami!!! Trzeba je znać

oto drobna modyfikacja Twojego kodu i już jest prawidłowo.

Kod:
float liczba1 = 4.2
float liczba2 = 1.4
float wynik = liczba1/liczba2
float rwynik = Round(wynik,0)

if  round(wynik - rwynik,10) == 0 then
    Message "Brak reszty - OK"
else
    Message "Jest reszta"
endif


Wystarczy że stwierdzisz ile miejsc znaczących chcesz porównywać.


2009-03-18, 10:24
Wyświetl profil
Wyświetl posty nie starsze niż:  Sortuj wg  
Odpowiedz w temacie   [ Posty: 8 ] 
   Podobne tematy   Autor   Odpowiedzi   Odsłony   Ostatni post 
Na tym forum nie ma nowych nieprzeczytanych postów. urlop każdego 1-go dnia miesiąca nie oblicza

w Programy Kadrowo Płacowe

poly

4

3117

2011-05-12, 22:51

SlowMag Wyświetl najnowszy post

Na tym forum nie ma nowych nieprzeczytanych postów. 50c szybkość działania

w Programy Księgowe

ryba

8

6429

2019-06-08, 09:41

wiwe Wyświetl najnowszy post

Na tym forum nie ma nowych nieprzeczytanych postów. test działania forum mojaSymfonia

[ Przejdź na stronę: 1, 2 ]

w Test

Paulina

15

34548

2013-06-17, 13:21

pawelp29 Wyświetl najnowszy post

Na tym forum nie ma nowych nieprzeczytanych postów. Pervasive - szybkość działania w sieci

w Techniczne

amo

3

4166

2015-02-05, 00:50

wrob Wyświetl najnowszy post



Kto jest online

Użytkownicy przeglądający to forum: Nie ma żadnego zarejestrowanego użytkownika i 11 gości


Nie możesz tworzyć nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Przejdź do:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Support forum phpbb by phpBB Assistant