#1 oxidián
Podívej se, co jednotlivé bitové operátory dělají, třeba tady. To by ti mělo pomoct k porozumění funkce a proč ti to padá :).
Fórum › C / C++
Ipow
Porad plati mrknout, co vlastne dela >> se signed integerem!!! Hlavne se zapornym cislem.
Nicmene je vcelku zbytecnost pocitat zaporny exponent, kdyz je vysledek cele cislo. Bude to vzdy 0 (maximalne pro 2^-1 bys mohl zaokrouhlit na 1)
No dyď se dívám, ale mě to nejde ladit. Dívám se na exp jaká nastala změna a nic není vidět v codeblock watch panelu. Toto nepomáhá.
#include "math_fnc.h"
int ipow(int base, int exp)
{
int result = 1;
if (exp>0)
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
else
while (exp)
{
if (exp & 0)
result *= base;
exp >>= 1;
if (exp & 0)
base *= base;
}
return result;
}
int ipow(int base, int exp)
{
int result = 1;
while (exp)
{
printf("base=%d exp=%d result=%d\n",base,exp,result);
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
printf("result=%d\n",result);
return result;
}
a prihodis ipow(4,-10) a pak to musis hodne rychle sejmout ctrl-c
A nebo radeji srovnani predchoziho exponentu s novym a pokud jsou stejne, tak ukoncit
#3 oxidián
Je taky možný celou funkci prostě předělat, aby fungovala. (Navíc jsem změnil návratový typ na double, aby šly vyjádřit i záporné mocniny.)
double ipow2(int base, int exp)
{
double result = 1;
int n = 0;
if (!exp) // exponent nula -> výsledek 1
{
return result;
}
else if (exp < 0) // exponent záporný
{
exp *= -1;
for (; n < exp; n++)
{
result *= base;
}
return (1 / result);
}
else
{
for (; n < exp; n++)
{
result *= base;
}
return result;
}
}
EDIT: Pochopitelně nevím, jak je na tom takhle funkce s výkonem, jediná optimalizace, která mě napadá, je hodit to do switche, namísto použití if-else formy. Netuším ovšem, zda se bitovými operátory něco šetří, neumím s nimi.
#8 oxidián
Pokud chceš integer, pak modifikovaná funkce může vypadat takhle:
int ipow2(int base, int exp)
{
double result = 1;
int n = 0;
if (!exp) // exponent nula -> výsledek 1
{
return 1;
}
else if (exp < 0) // pro int nejde, vrací se nula
{
return 0;
}
else
{
for (; n < exp; n++)
{
result *= base;
}
return result;
}
}
#7 oxidián
problem je v tom, ze se to do kladnych cisel nedostane... jen bitovej posun nad zapornym cislem neposouva bit se znamenkem. Takze tam mas proste porad aspon -1 (protoze zaporna nula neexistuje)
base=4 exp=-5 result=1
base=16 exp=-3 result=4
base=256 exp=-2 result=64
base=65536 exp=-1 result=64
base=0 exp=-1 result=4194304
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
base=0 exp=-1 result=0
Ale kdyz nechapes, co se vypisuje, tak musi byt sakra narocny cokoliv funkcniho vubec udelat (podle diskuzi aplikujes geneticke programovani - pokus-omyl uplne naslepo - bez jakykoliv znalosti a uz vubec ne chapani co delas)
#10 KIIV
KIIVe, nejsou ty výsledky stejně nějak mimo? 16 na -3 se určitě nerovná 4. Pochopil jsem doufám správně, že oxidián chce funkci na výpočet mocnin :D. Pokud jsem byl mimo, tak je problém mezi klávesnicí a židlí tady u mě.
#11 ondrej39
je to jeho kod s vypisem promennych (prispevek #5) (a je to na zacatku cyklu - hodnoty, co vstupuji do vypoctu, takze o kolo pozadu)
4^-3 je 1/4^3 coz je 1/64 -> Proto je taky zbytecne ty zaporne exponenty resit. Proste vratit 0
Jo a jeste k posunu toho exponentu:
-5 = 0xfffffffb
-3 = 0xfffffffc
-2 = 0xfffffffe
-1 = 0xffffffff
(kdyby nahodou nekoho zaujal prechod z -5 na -3 pri bitovem posunu... pro kladne by to bylo 5 (0b101), 2 (0b10), 1 0
Ten kód jsem našel na internetu, když jsem hledal kód na mocninu integru. Chápat bitovou matematiku se teprve učím. A ano učím se to tak, že vezmu kód a zjišťuji co dělá.
int ipow(int base, int exp)
{
int result = 1;
int n = 0;
if (exp<=0)
return 0;
else
while (exp) {
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
}
Chápat bitovou matematiku se teprve učím.
Binární algebra funguje úplně stejně jako dekadická. Nevím, jak je to dnes, ale "za nás" se to probíralo v matematice na střední škole.
Upřímně mi pořád nějak uniká, proč to řešit bitovými posuny, když to jde úplně v pohodě bez nich.
Taky si myslím. V podstatě stačí cyklus for a násobení. V případě, že exponent nebude kladný, vrátí to 1.
hu
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Moderátoři diskuze