je to super programek ten dc, jen mi neni jasne, jak mohu udelat odmocninu vyssiho stupne. Zkusil jsem 10 1 3 /^p, ale vykriklo to na mne..."Runtime warning: non-zero scale in exponent". Nechce se mi verit, ze by u takovehoto programu neslo pouzivat racionalni exponenty, nebo se mylim?:-(
crpp15:~/fcc fik$ bc -l
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
e(l(10)/3)
2.15443469003188372173
to je moc škoda - "bc" mi připadá proti "dc" jako kanón proti praku a to nejen v pozitivním smyslu výkonosti, tak i v negativním (na některé věci poněkud neohrabaný). Kdybych uměl dobře programovat, asi bych nabídl autorovi pomoc s rozšířením... s logaritmama, goniom.fcema a racionalnima mocninama, by tento program v mých očích nebyl jen dobrý, ale skoro genialní:)
Problem je hlavne v tom, ze DC je uz historicka aplikace (dokonce starsi nez samotne cecko :-), kterou nikdo nemuze/nechce zmenit aniz by doslo k naruseni fungujicich skriptu. Ale rozsireni by bylo fajn, stacilo by pouzit nejaky zbesily prefix pro nove operace, ktery by nekolidoval se jmeny registru a prikazu. Dulezite by taky muselo byt, aby DC na nicem dalsim nezaviselo - max. na stdlibu - opet kvuli prenositelnosti.
Ptal jsem se autora, jestli se uvazuje s rozsirenim a krome doporuceni uchylit se k "bc", mi dal jeste jednu, pomerne zajimavou radu:
"Get a version of bc that compiles to dc bytecode. (GNU bc does not. OpenBSD has a version that does.) Get a copy of the bc source for the above functions and ask bc to generate the bytecode instead of running the output. (The GNU bc version of the math library code has been shown by several tests to be faster than other implementations.)"
Jestli tomu dobre rozumim, tak ten OpenBSD je schopnej produkovat jakysi bytecode, ktery umi zrejme "dc" vyuzivat jako nejaka makra ci knihovny. To bych si pak mohl pomoci toho OpenBSD vykrouzit "dc" k dokonalosti (log, sin, cos...:)... - no nevim, nechci jasat predcasne, vyzkousim a kdyz dopadnu dobre, dam sem vedet...
On byl puvodne "bc" postaven jako nadstavba "dc" (psal jsem o tom tusim v prvni casti). "bc" fungoval pomoci maker, ktere on-the-fly prevadely jeho prikazy na prikazy "dc" - tim se mimo jine vysvetluje, proc ma POSIXove "bc" tolik omezeni, napriklad na jednopismenna jmena promennych.
Takze pokud nekdo vzal puvodni zdrojaky "bc" (psane jako makra pro "dc" a nikoli ceckovsky zdrojak), tak je asi opravdu jednoduche generovat bytekod - tim se pravdepodobne mysli skript pro "dc", ktery se opravdu nekdy podoba sumu na lince nez zdrojovemu kodu :-)))
Ale nevim, sam pouzivam GNU bc i GNU dc a oboji je psano v cecku. Pokud se Ti podari rozschodit tu OpenBSD verzi i na Linuxu, dej prosim vedet (napriklad sem do fora), dost me to zajima.
Máme tu v práci i FreeBSD servery, takže jsem to hned zkouknul ..
Je pravda, že se produkuje nějaký "mezikód" pro dc - v jednom ze souborů je vidět definice e^x, ln(x), sin(x), cos(x) ..
Celkově to ale zkompilovat nejde, protože BSD používá automake nekompatibilní s linuxovým.
Kdybyste někdo měl zájem, můžu to ev. přeposlat (zdrojáky mají cca 150 kB). Licenčně by to snad mělo být v pořádku, protože je tam zmínka o GNU GPL 2 ..
.. a ještě ukázka pro zvědavé (redaktoři a čtenáři root-a prominou, ale je to trochu delší) - defince exp(x) :
/* Uses the fact that e^x = (e^(x/2))^2
When x is small enough, we use the series:
e^x = 1 + x + x^2/2! + x^3/3! + ...
*/
define e(x) {
auto a, d, e, f, i, m, n, v, z
/* a - holds x^y of x^y/y! */
/* d - holds y! */
/* e - is the value x^y/y! */
/* v - is the sum of the e's */
/* f - number of times x was divided by 2. */
/* m - is 1 if x was minus. */
/* i - iteration count. */
/* n - the scale to compute the sum. */
/* z - orignal scale. */
/* Check the sign of x. */
if (x<0) {
m = 1
x = -x
}
/* Precondition x. */
z = scale;
n = 6 + z + .44*x;
scale = scale(x)+1;
while (x > 1) {
f += 1;
x /= 2;
scale += 1;
}
/* Initialize the variables. */
scale = n;
v = 1+x
a = x
d = 1
for (i=2; 1; i++) {
e = (a *= x) / (d *= i)
if (e == 0) {
if (f>0) while (f--) v = v*v;
scale = z
if (m) return (1/v);
return (v/1);
}
v += e
}
}
Bezvadny, takhle by bylo mozne napsat i dalsi funkce (napr. goniometricke), ktere se daji rozlozit na radu, napr. Taylorovym rozvojem. Co napriklad vyleze u te funkce exp() za mezikod pro "DC"? Muzete to prosim vyzkouset?