Ez egy önmegválaszolt kérdés, az a kérdés, amely ésszerűen felteszi a kérdést, a válasz részben található. Kérjük, ne szavazzon, mert úgy gondolja, hogy nem kutattam eleget a válaszhoz. Köszönöm. Mindenesetre a bc ezen tulajdonságának nincs leírása (amit megtalálok) ezen a webhelyen.
A bc
használatakor a %
operátor azt állítja, hogy kiszámítja a “maradékot”, és igen, egész számok esetén működik, és ha a skála nulla :
$ bc <<<" scale=0; 27 % 7 " 6
De nem adja meg az” egész szám maradékot “, ha a skála nem nulla:
$ bc <<<" scale=10; 27 % 7 " .0000000003
Miért (vagy hogyan) hasznos a %
modulo definíciója?
Válasz
A %
operátort egyértelműen határozza meg a bc
kézikönyv [a] néven:
# Internal % operator definition: define internalmod(n,d,s) { auto r,oldscale; oldscale=scale; r=n/d; s=max(s+scale(d),scale(n)); scale=s; r = n-(r)*d; scale=oldscale; return(r) }
Feltételezve, hogy max
a következő:
define max(x,y){ if(x>y){return(x)};return(y) }
Hogyan hasznos ez a hosszú meghatározás?
-
Egész maradék .
I “mind ainternalmod
függvény és a%
operátor eredményei bizonyítják, hogy egyenértékűek a következő műveletek némelyikével.Ha a számok egészek, akkor A skála értéke 0, ez az egész szám fennmaradó függvény.
$ bc <<<"n=17; d=3; scale=0;a=internalmod(n,d,scale);b=n%d;print a," ",b,"\n"" 2 2 $ bc <<<"n=17; d=6; scale=0;a=internalmod(n,d,scale);b=n%d;print a," ",b,"\n"" 5 5
Ez nem ugyanaz, mint a matematikai mod függvény. Ezt alább megoldom.
-
Tizedes maradék.
Ha an
szám hosszabb tizedesjegy, és módosítjuk a skálát, akkor ezt kapjuk:$ bc <<<"n=17.123456789;d=1; scale=0 ;a=internalmod(n,d,scale);b=n%d; print a," ",b,"\n"" .123456789 .123456789 $ bc <<<"n=17.123456789;d=1; scale=3 ;a=internalmod(n,d,scale);b=n%d; print a," ",b,"\n"" .000456789 .000456789
Vegye figyelembe, hogy itt az első 3 tizedesjegyet eltávolítottuk, és a fennmaradó rész a negyedik tizedesjegyből származik.
$ bc <<<"n=17.123456789;d=1; scale=7 ;a=internalmod(n,d,scale);b=n%d; print a," ",b,"\n"" .000000089 .000000089
Ez azt mutatja, hogy a maradék a definíció sokoldalúbbá teszi.
Most ez áll: a maradék után a skála értéke.
-
Méretváltozás A méretváltoztatásra azért van szükség, mert a
d
(osztó) számnak több tizedesjegye lehet, mint an
számban. Ebben az esetben több tizedesjegyre van szükség a pontosabb eredmény eléréséhez:$ bc <<<"n=17.123456789; d=1.00000000001; scale=0; a=internalmod(n,d,scale); b=n%d; print a," ",scale(a)," -- ", b," ",scale(b),"\n"" .12345678883 11 -- .12345678883 11
És ha a skála változik e:
$ bc <<<"n=17.123456789; d=1.00000000001; scale=5; a=internalmod(n,d,scale); b=n%d; print a," ",scale(a)," -- ", b," ",scale(b),"\n"" .0000067888287655 16 -- .0000067888287655 16
Amint a fentiekből látható, a skála értéke megváltozik, és a ,
d
ésscale
.
I” Feltételezem, hogy a internalmod
és a %
operátor összehasonlításával mindkettő egyenértékűnek bizonyult.
-
iv Zavartság . Legyen óvatos, mert a
d
értékével való játék zavaróvá válhat:$ bc <<<"n=17.123456789; d=10; scale=3; a=n%d; print a," ",scale(a),"\n"" .003456789 9
És:
$ bc <<<"n=17.123456789; d=1000; scale=3; a=n%d; print a," ",scale(a),"\n"" .123456789 9
Azaz: a
d
(1 felett) értéke módosítani fogja a beállított méretarány értékét.
Valószínűleg az d
1-től eltérő értéke esetén a scale = 0 értéket kell használnia (hacsak nem igazán tudja, mit csinál).
-
Matematikai mod .
Mivel egy ilyen mély merülést a mod függvényekbe, valószínűleg tisztáznunk kell a%
valós hatását abc
fájlban. A bc%
operátora “csonkoló osztást” használ. A0
felé fordul. Ez fontos an
és / vagyd
negatív értékei esetében:$ bc <<<"scale=0; n=13; d=7; n%d; " 6 $ bc <<<"scale=0; n=13; d=-7; n%d; " 6
A maradék előjele a
dividend
előjelét követi.$ bc <<<"scale=0; n=-13; d=7; n%d; " -6 $ bc <<<"scale=0; n=-13; d=-7; n%d; " -6
Bár helyes A math modnak mindig pozitív maradékot kell adnia a számára.
Az (egész) mod függvény megszerzéséhez használja a következőt:
# Module with an always positive remainder (euclid division). define modeuclid(x,div) { if(div!=int(div)){ "error: divisor should be an integer ";return(0)}; return(x - div*int(x/div)) }
És (akkor) ez működni fog:
$ bc <<<"n=7.123456789; d=5; modeuclid(34.123456789,7)" 6.123456789
[a]
expr% expr
A kifejezés eredménye a “maradék”, és az alábbiakban kerül kiszámításra út. A% b kiszámításához először az a / b-t kell kiszámítani a számjegyek skálájára.Ezt az eredményt használjuk az a- (a / b) * b kiszámításához a skála + skála (b) és skála (a) maximális skálájára.
Ha a skála nulla, és mindkét kifejezés egész szám, akkor ez a kifejezés az egész szám fennmaradó függvény. vezették be, hogy megfelelően működjön, definiáljon egy álnevet:$ alias bc="bc -l "$HOME/.func.bc""
És hozzon létre egy
$HOME/.func.bc
nevű fájlt, amely ( legalább):# Internal % operator definition: define internalmod(n,d,s) { auto r,oldscale; oldscale=scale; r=n/d; s=max(s+scale(d),scale(n)); scale=s; r = n-(r)*d; scale=oldscale; return(r) } # Max function define max(x,y){ if(x>y){return(x)};return(y) } # Integer part of a number toward 0: -1.99 -> -1, 0.99 -> 0 define int(x) { auto os;os=scale;scale=0; x=sgn(x)*abs(x)/1;scale=os;return(x) } define sgn (x) { if (x<0){x=-1};if(x>0){x=1};return(x) }; define abs (x) { if (x<0) x=-x; return x }; # Module with an always positive remainder (euclid division). define modeuclid(x,div) { if(div!=int(div)){ "error: divisor should be an integer ";return(0)}; return(x - div*int(x/div)) }
A tetszőleges szám (egész vagy nem egész) mod függvénye meghatározható:
# Module with an always positive remainder (euclid division). define modeuclid(x,div) { div=abs(div);return(x - div*floor(x/div)) } # Round down to integer below x (toward -inf). define floor (x) { auto os,y;os=scale;scale=0; y=x/1;if(y>x){y-=1};scale=os;return(y) };
Ez a meghatározás matematikai szabályok szerint tökéletesen helytálló és helyes, azonban meglehetősen zavaróvá válhat, amikor valós esetekben próbálják alkalmazni, csak mondván.