BC: Hogyan hasznos a 0-tól eltérő skálájú „modulo” (%)?

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?

  1. Egész maradék .
    I “mind a internalmod 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.

  1. Tizedes maradék.
    Ha a n 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.

  1. 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 a n 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 és scale.

I” Feltételezem, hogy a internalmod és a % operátor összehasonlításával mindkettő egyenértékűnek bizonyult.

  1. 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).

  1. 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 a bc fájlban. A bc % operátora “csonkoló osztást” használ. A 0 felé fordul. Ez fontos a n és / vagy d 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.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük