Witam, mam liczbe zmienno przecinkowa i chcialbym ja zamienic na liczbe calkowita, jednak z zachowaniem zasad zaokraglania. Jaka funkcja to czyni?
- posted
19 years ago
Witam, mam liczbe zmienno przecinkowa i chcialbym ja zamienic na liczbe calkowita, jednak z zachowaniem zasad zaokraglania. Jaka funkcja to czyni?
(int) (a + 0.5), na przykład
Waldek
#include <stdio.h>
int main( void ) { double a=0.9999, b=1.0000; printf( "%.4lf + %.4lf = %d\n", a, b, (int) (a+b) ); return 0; }
Co otrzymamy w wyniku? Oczywiście, że jeden! Z liczbami zmienno przecinkowymi jest trochę klopotu, i trzeba być bardzo ostrożnym. Jak pamietam (x86-visual-c++-6.0) to taka funkcję (dobrą) sam musiałem sobie napisać. A zasady zaokrąglania można nietrudno zaimplementować.
No, no, trochę przesadziłem... to nie jest takie łatwe, w zależności jakie sobie przyjmiesz założenia, do którego miejsca zaokrąglanie, ile miejsc po przecinku brać pod uwagę. Zrobienie uniwersalnej funkcji nie jest łatwe. Jeśli masz mało miejsca w swoim avr-ku to zastanowiłbym się nad implementacją stałego przecinka.
Tue, 15 Feb 2005 22:17:57 +0100, na pl.misc.elektronika, Łukasz Góralczyk napisał(a):
Prawda, zwłaszcza że są jeszcze jakieś specjalne szczególiki wymagane w księgowości. Ale tu miało byc zwyczajne zaokrąglenie do całkowitych, IMHO ze zwyczajowym : część ułamkowa <0.5 - do dołu , >=0.5 - do góry. Wtedy wystarczy np.
int Round(double value) { double tolow=floor(value); if((value-tolow) < 0.5) return (int)tolow; else return (int)tolow+1 ; }
A i tak dużo zasobów pochłania.
Hmmm.... Nie prościej: int(value + 0.5)?
Oczywiście implementacja i sposób użycia argumentów zależny od jężyka programowania ale dotąd uzywałem zawsze (już kilkanaście lat) tego sposobu i jest niezawodny.
Użytkownik Łukasz Góralczyk napisał:
No oczywiście.. 1+0.999 = 1.9999, ale że konwersja (int) ucina po prostu końcówkę to dostajemy 1. Gdyby zrobić tak jak podane wyżej: (int) (a+b+0.5) byłby chyba dobry wynik ?!?
Użytkownik RoMan Mandziejewicz napisał:
<ciach>
A do zaokrąglania do dowolnego miejsca po przecinku taka konwersja też sie sprawdza (oczywiście pochłania trochę liczenia ;/
float a = 1.738287; float wynik; int miejsce = 2;
wynik = ( ( (int) (a*pow(10,miejsce) + 0.5) )/pow(10,miejsce));
-> wynik == 1.7400
Nie miałem z tym raczej problemów, więc po co sobie komplikować życie ;-)
[...]
Mało tego - mozna jej uzyć do zaokrąglania niekoniecznie do liczby miejsc po przecinku... Implementacja moja - ciekaw jestem, kto rozpozna język ;-) Funkcja zawiera błąd przy zaokragleniu w górę - działanie swiadome, wynikające z wiedzy, że zaokrąglana liczba nie ma aż tylu miejsc po przecinku. Napisana 11.07.1993 roku ;-)
Parametry: KWOTA - liczba do zaokrąglenia DO - z jaką dokładnością zaokrąglamy (2 miejsca po przecinku to
0.01, z dokładnością do tysięcy: 1000) - bardzo ciekawe efekty występują przy stosowaniu ciekawych liczb ;->===8<=== PARAMETERS KWOTA, DO, METODA
DO CASE CASE M.METODA = 1 && ZAOKRĄGENIE KSIĘGOWE M.METODA = 0.5 CASE M.METODA = 2 && ZAOKRĄGLENIE W GÓRĘ M.METODA = 0.999999 CASE M.METODA = 3 && ZAOKRĄGLENIE W DÓŁ M.METODA = 0 ENDCASE
RETURN SIGN(M.KWOTA) * M.DO * INT(ABS(M.KWOTA/M.DO)+M.METODA) ===8<===
On Tue, 15 Feb 2005 22:44:47 +0100, Jurek Szczesiul snipped-for-privacy@wycin.ep.com.pl> wrote: [.....]
A próbowaleś przynajmniej sprawdzić jak rozwiązanie Waldka zadziała np. dla 1.49, 1.50 i 1.51? :-) A jest mniej kosztowne - tylko jedno dodawanie zmiennoprzecinkowe. Problem jest taki, że dla liczb ujemnych będzie działać niekoniecznie tak, jakbyśmy tego oczekiwali. :-) Twoje zdaje się również będzie działać w podobny sposób. :-)
Regards, /J.D.
On Tue, 15 Feb 2005 22:49:49 +0100, RoMan Mandziejewicz snipped-for-privacy@pik-net.pl wrote: [.....]
Dla liczb ujemnych równiez jest niezawodny? :-)
Regards, /J.D.
Trochę dalej podałem konkretną funkcję... Sprawdź.
Tue, 15 Feb 2005 22:49:49 +0100, na pl.misc.elektronika, RoMan Mandziejewicz napisał(a):
Pewnie , że prościej. Nie ma to jak sobie pokomplikować życie ;-[
Jasne, że spróbowałem - tylko oko krzywo spojrzało na wynik ;-[
- i nastąpiła wędrówka obwodnicą ;-)
Podana funkcja implementuje coś innego niż int(value + 0.5).
Regards, /J.D.
Piotr Buczynski wrote: [ciach]
Umnkęło mi, że kolega postujący chciał zaokrąglenia do liczby całkowitej
- to upraszcza problem (jeden z kolegów podał już poprawne rozwiązanie).
A co do 0.5:
#include <stdio.h>
int main( void ) { double a=0.1, b=1.0; printf( "%.4lf + %.4lf = %d\n", a, b, (int) (a+b+0.5) ); return 0; }
Powinno być 2, a jest nadal 1 :) . Pozdrawiam serdecznie.
Chyba się nie wyspałeś. Zaokrąglenie 1.1 ma dać 2?
powinno być 1 i nadal jest 1. 1.0 + 0.1 = 1.1, zaokrąglone wychodzi 1.
Waldek
Ej spiochy - a 0.5 widzicie ?
To co przepraszam robi avr-gcc z -1.6 przy konwersji ?
J.
0.5 jest 'poprawką' służacą do poprawnego zaokrąglania. I jest rzeczą oczywistą, że in(1.6) daje w wyniku 1. [...]
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.