Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[C++] Float lub double do unsigned

1 view
Skip to first unread message

SuperMann

unread,
Dec 18, 2009, 4:30:41 AM12/18/09
to
Witam,
mam nastepujacy problem. W srodowisku C++ Builder 2010 musze napisac bardzo
prosty program, ktory wczyta liczbe zmiennoprzecinkowa a wyswietli w postaci
unsigned.
No niby nic ale rece mi opadaja jesli chodzi o zachowanie precyzji.
Z klawiatury uzywajac "cin >> SUMA" wprowadzam liczbe 49,97 do zmiennej typu
float,
nastepnie przeprowadzam operacje SUMA100 = SUMA * 100; i ku mojemu w SUMA100
zamiast 4997 mam 4996.
Czy moglby mi ktos powiedziec jak rozwiazac tak banalny problem?

Pozdrawiam
SM


Paweł Kierski

unread,
Dec 18, 2009, 4:34:30 AM12/18/09
to

Tomasz Kaczanowski

unread,
Dec 18, 2009, 4:34:44 AM12/18/09
to
SuperMann pisze:

U�ywa� liczb zmiennoprzecinkowych, rozumiej�c jak one dzia�aj� i jak je
wykorzysta�. Nie wsz�dzie si� nadaj�...


--
Kaczus
http://kaczus.republika.pl

SuperMann

unread,
Dec 18, 2009, 4:47:48 AM12/18/09
to

U�ytkownik "Tomasz Kaczanowski" <kaczus@dowyciecia_poczta.onet.pl> napisa� w
wiadomo�ci news:hgfibj$63h$1...@news.onet.pl...

> U�ywa� liczb zmiennoprzecinkowych, rozumiej�c jak one dzia�aj� i jak je
> wykorzysta�. Nie wsz�dzie si� nadaj�...

Tak sie sklada ze doskonale wiem jak one dzialaja, ale w C++ jestem
swiezakiem i sadzilem ze jest jakis prosty sposob na obejscie problemu tzw.
zaokraglania finansowego z wykorzystaniem podstawowych modulow. Nie chce
korzystac z dodatkowych klas typu Currency ktora rozwiazala by moj problem.
Chce poprostu wczytac liczbe 49.97 i wystwietlic ja juz jako unsigned czyli
4997. Masz jakis pomysl?

Pozdr


Mariusz Marszałkowski

unread,
Dec 18, 2009, 5:02:00 AM12/18/09
to
On 18 Gru, 10:47, "SuperMann" <n...@email.com> wrote:
> Użytkownik "Tomasz Kaczanowski" <kaczus@dowyciecia_poczta.onet.pl> napisał w
> wiadomościnews:hgfibj$63h$1...@news.onet.pl...
>
> > Używać liczb zmiennoprzecinkowych, rozumiejąc jak one działają i jak je
> > wykorzystać. Nie wszędzie się nadają...

>
> Tak sie sklada ze doskonale wiem jak one dzialaja, ale w C++ jestem
> swiezakiem i sadzilem ze jest jakis prosty sposob na obejscie problemu tzw.
> zaokraglania finansowego z wykorzystaniem podstawowych modulow. Nie chce
> korzystac z dodatkowych klas typu Currency ktora rozwiazala by moj problem.
> Chce poprostu wczytac liczbe 49.97 i wystwietlic ja juz jako unsigned czyli
> 4997. Masz jakis pomysl?
>
> Pozdr

Sprawdzić czy sufit czy podłoga leży bliżej i bliższą zapisać do
unsigned.
Pozdrawiam


Jacek Czerwinski

unread,
Dec 18, 2009, 5:18:04 AM12/18/09
to
SuperMann pisze:

>> U�ywa� liczb zmiennoprzecinkowych, rozumiej�c jak one dzia�aj� i jak je

>> wykorzysta�. Nie wsz�dzie si� nadaj�...


>
> Tak sie sklada ze doskonale wiem jak one dzialaja,

No w�asnie kol Tomaszowi sie wydaje (mi te�), �e nie bardzo...

> ale w C++ jestem swiezakiem

Dzia�aj� tak samo, jak w innych j�zykach (o ile maj� koncepcj� floata,
czyli w przybli�eniu w j�zykach kompilowanych)

Marek Borowski

unread,
Dec 18, 2009, 5:41:16 AM12/18/09
to
Na pierszy rzut oka wydaje sie ze chodzi tu o nieznajomosc typu float.
Ale jest male ale. 49,97 da sie niezle zapreprezentowac we typowym
floacie czyli 32 bitowych. Watpie aby uzywano 16bitowych floatow
(ogolnie to sa zdefiniowane). Problem ma jakies drugie dno.

Najblizsze 49,97 jest 49,97000122 ktore ma postac binarna:
0 10000100 100 0111 1110 0001 0100 1000

czyli przypominajac:

znak 0
wykladnik 5
mantysa 1 + 0,5 + 0,03125 + 0,015625 + 0,0078125 + 0,00390625 +
0,001953125 + 0,000976563 +3,05176E-05 + 7,62939E-06 + 9,53674E-07 =
1,561562538

co daje 1,561562538 * 32 = 49,97000122

U mnie program:

float a;
int b;
std::cin >> a;
b = a * 100;
std::cout << b;

dziala zgodnie z oczekiwaniami pytajacego. Chodzi chyba o cos innego.


Pozdrawiam

Marek

Jacek Czerwinski

unread,
Dec 18, 2009, 5:50:12 AM12/18/09
to
Marek Borowski pisze:

> Jacek Czerwinski wrote:
>> SuperMann pisze:
>>
>>>> U�ywa� liczb zmiennoprzecinkowych, rozumiej�c jak one dzia�aj� i jak
>>>> je wykorzysta�. Nie wsz�dzie si� nadaj�...
>>>
>>> Tak sie sklada ze doskonale wiem jak one dzialaja,
>> No w�asnie kol Tomaszowi sie wydaje (mi te�), �e nie bardzo...
>>
>> > ale w C++ jestem swiezakiem
>> Dzia�aj� tak samo, jak w innych j�zykach (o ile maj� koncepcj� floata,
>> czyli w przybli�eniu w j�zykach kompilowanych)
>>
> Na pierszy rzut oka wydaje sie ze chodzi tu o nieznajomosc typu float.
> Ale jest male ale. 49,97 da sie niezle zapreprezentowac we typowym
> floacie czyli 32 bitowych. Watpie aby uzywano 16bitowych floatow
> (ogolnie to sa zdefiniowane). Problem ma jakies drugie dno.
>
> Najblizsze 49,97 jest 49,97000122 ktore ma postac binarna:
> 0 10000100 100 0111 1110 0001 0100 1000

Byďż˝ (wieki temu, przed netem) artykuďż˝ o 'Real Progragramers'. Otďż˝
prawdziwy programista debuguje b��dy zmiennego przecinka patrz�c w kod
szesnastkowy. Gratulacje ;)

na serio mo�esz miec racj�.

Jak nie wiadomo o co chodzi, (a tym przypadku wyj�tkowo) chodzi o
ulepszenia Borlanda. W wielu miejscach BCB nie chce szokowa� u�ytkownika
d�ugimi ci�gami zer i potem cyferka (lub seri� dziewi�tek) i dla jego
dobra mu to us�u�nie zaokr�gli. Bardzo go za to szanuj�.


Marek Borowski

unread,
Dec 18, 2009, 6:06:28 AM12/18/09
to
Tak naprade to nalezaloby sie przyjzec liczbie 4997 i instrukcji
koprocesora FIST. A ta zaokragla dane zgodnie z ustawieniami rejestru
kontrolnego. (w gore, w dole, stadardowo, obciecie). Czyli masz racje
to jest sprawa kompilatora.

Pozdrawiam

Marek


Artur M. Piwko

unread,
Dec 18, 2009, 6:22:52 AM12/18/09
to
In the darkest hour on Fri, 18 Dec 2009 10:47:48 +0100,
SuperMann <n...@email.com> screamed:

> Tak sie sklada ze doskonale wiem jak one dzialaja, ale w C++ jestem
> swiezakiem i sadzilem ze jest jakis prosty sposob na obejscie problemu tzw.
> zaokraglania finansowego z wykorzystaniem podstawowych modulow. Nie chce
> korzystac z dodatkowych klas typu Currency ktora rozwiazala by moj problem.
> Chce poprostu wczytac liczbe 49.97 i wystwietlic ja juz jako unsigned czyli
> 4997. Masz jakis pomysl?
>

Jest. Używać 4997 od samego początku i zapomnieć o float/double.

--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:223B ]
[ 12:22:25 user up 12290 days, 0:17, 1 user, load average: 0.90, 0.28, 0.72 ]

One with God is a majority. -- Billy Graham

SuperMann

unread,
Dec 18, 2009, 8:21:12 AM12/18/09
to

U�ytkownik "Marek Borowski" <ma...@lidersdpl.com> napisa� w wiadomo�ci
news:hgfm8d$hhr$1...@news.onet.pl...
> Jacek Czerwinski wrote:

> Na pierszy rzut oka wydaje sie ze chodzi tu o nieznajomosc typu float.
> Ale jest male ale. 49,97 da sie niezle zapreprezentowac we typowym floacie
> czyli 32 bitowych. Watpie aby uzywano 16bitowych floatow (ogolnie to sa
> zdefiniowane). Problem ma jakies drugie dno.
>
> Najblizsze 49,97 jest 49,97000122 ktore ma postac binarna:
> 0 10000100 100 0111 1110 0001 0100 1000

Hmm.. no niby tak powinno byc, ale w Builderze wychodzi 49,969997406.
Poradzilem sobie z tym problemem obchodzac go poprzez dodanie 0,005 i
dopiero wtedy przemnozeniu przez 100.

Pozdr


Marek Borowski

unread,
Dec 18, 2009, 1:44:56 PM12/18/09
to
SuperMann wrote:
> U�ytkownik "Marek Borowski" <ma...@lidersdpl.com> napisa� w wiadomo�ci
> news:hgfm8d$hhr$1...@news.onet.pl...
>> Jacek Czerwinski wrote:
>
>> Na pierszy rzut oka wydaje sie ze chodzi tu o nieznajomosc typu float.
>> Ale jest male ale. 49,97 da sie niezle zapreprezentowac we typowym floacie
>> czyli 32 bitowych. Watpie aby uzywano 16bitowych floatow (ogolnie to sa
>> zdefiniowane). Problem ma jakies drugie dno.
>>
>> Najblizsze 49,97 jest 49,97000122 ktore ma postac binarna:
>> 0 10000100 100 0111 1110 0001 0100 1000
>
> Hmm.. no niby tak powinno byc, ale w Builderze wychodzi 49,969997406.
> Poradzilem sobie z tym problemem obchodzac go poprzez dodanie 0,005 i
> dopiero wtedy przemnozeniu przez 100.
>
A tak z ciekawosci, sprobuj dodac:

#include <float.h>

i na poczatku programu:

_control87(RC_NEAR, MCW_RC);


Pozdr

Marek

Paweł Kierski

unread,
Dec 19, 2009, 1:50:29 PM12/19/09
to
W dniu 2009-12-18 10:47, SuperMann pisze:

> U�ytkownik "Tomasz Kaczanowski"<kaczus@dowyciecia_poczta.onet.pl> napisa� w
> wiadomo�ci news:hgfibj$63h$1...@news.onet.pl...
>
>> U�ywa� liczb zmiennoprzecinkowych, rozumiej�c jak one dzia�aj� i jak je
>> wykorzysta�. Nie wsz�dzie si� nadaj�...
>
> Tak sie sklada ze doskonale wiem jak one dzialaja, ale w C++ jestem
> swiezakiem

Czyli nie wiesz, jak one działają w C++.

> i sadzilem ze jest jakis prosty sposob na obejscie problemu tzw.
> zaokraglania finansowego z wykorzystaniem podstawowych modulow.

C++ ma wśród typów prostych typy zmiennoprzecinkowe i całkowite.
Podstawowych modułów, które by to załatwiały nie ma.

> Nie chce
> korzystac z dodatkowych klas typu Currency ktora rozwiazala by moj problem.
> Chce poprostu wczytac liczbe 49.97 i wystwietlic ja juz jako unsigned czyli
> 4997. Masz jakis pomysl?

Zmienić język programowania na taki, który w podstawowym zestawie ma
typy do obsługi wartości finansowych. Albo przełamać się i użyć
jakiejś biblioteki w C++.

--
Paweł Kierski
ne...@pkierski.net

Adam Wysocki

unread,
Dec 19, 2009, 10:53:02 PM12/19/09
to
SuperMann <n...@email.com> wrote:

> No niby nic ale rece mi opadaja jesli chodzi o zachowanie precyzji.
> Z klawiatury uzywajac "cin >> SUMA" wprowadzam liczbe 49,97 do zmiennej typu
> float,
> nastepnie przeprowadzam operacje SUMA100 = SUMA * 100; i ku mojemu w SUMA100
> zamiast 4997 mam 4996.


> Czy moglby mi ktos powiedziec jak rozwiazac tak banalny problem?

P�na pora wi�c mo�e nie my�l� logicznie, ale je�eli po przecinku s� zawsze
dwa miejsca, to:

int a, b;
scanf("%d,%d", &a, &b);
printf("%d\n", a * 100 + b);

powinno za�atwi� problem.

--
http://www.gophi.pl/

Adam Wysocki

unread,
Dec 19, 2009, 10:53:14 PM12/19/09
to
SuperMann <n...@email.com> wrote:

> Czy moglby mi ktos powiedziec jak rozwiazac tak banalny problem?

P�na pora wi�c mo�e nie my�l� logicznie, ale je�eli po przecinku s� zawsze

Paweł Kierski

unread,
Dec 20, 2009, 3:17:06 AM12/20/09
to
W dniu 2009-12-20 04:53, Adam Wysocki pisze:

W�a�nie powoli wymy�lasz rozwi�zanie ze sta�oprzecinkow� arytmetyk�
w obliczeniach finansowych - tu akurat liczenie w groszach, choďż˝
praktycznie stosuje siďż˝ np. setne grosza.

--
Paweďż˝ Kierski
ne...@pkierski.net

Bronek Kozicki

unread,
Dec 20, 2009, 8:19:19 AM12/20/09
to

konwersje ze zmiennoprzecinkowej do całkowitej w C (i C++) działają
poprzez obcięcie części ułamkowej. Twój sposób jest prawidłowy, bo
dzięki zwiększeniu liczby o połowę progu obcięcia wprowadziłeś
zaokrąglenie. Lepiej to widać gdy zamienić kolejność działań:
const double suma = 49.97;
const int suma100 = suma * 100.0 + 0.5;


B.

Paweł Kierski

unread,
Dec 21, 2009, 4:00:21 AM12/21/09
to
Bronek Kozicki wrote:
[...]

> konwersje ze zmiennoprzecinkowej do całkowitej w C (i C++) działają
> poprzez obcięcie części ułamkowej. Twój sposób jest prawidłowy, bo
> dzięki zwiększeniu liczby o połowę progu obcięcia wprowadziłeś
> zaokrąglenie. Lepiej to widać gdy zamienić kolejność działań:
> const double suma = 49.97;
> const int suma100 = suma * 100.0 + 0.5;

Co do prawidłowości to należałoby to jeszcze skonsultować z lokalnymi
prepisami księgowymi, jeśli są to wartości dotyczące pieniędzy.
Zazwyczaj jest to coś podobnego do dodania 0.5, ale lepiej się nie
zdziwić...

--
Paweł Kierski
ne...@pkierski.net

Bronek Kozicki

unread,
Dec 21, 2009, 2:41:36 PM12/21/09
to

a przepraszam, nie zauważyłem że mowa o pieniądzach. W takim kontekście
zasady zaokrąglania zależą od kontekstu operacji.


B.

0 new messages