GNU BC : 척도가 0이 아닌 “모듈로”(%)는 어떻게 유용합니까?

이것은 자체 답변 질문입니다. 질문을하기에 합당한 조사는 답변 부분에 있습니다. 제가 답변을 충분히 조사하지 않았다고 생각하므로 반대표를 던지지 마십시오. 감사. 어쨌든이 사이트에는 bc의 이러한 특성에 대한 설명이 없습니다.

bc를 사용할 때 % 연산자는 “나머지”를 계산한다고 주장하며 예, 정수 숫자에 대해 작동하며 스케일이 0 일 때 :

$ bc <<<" scale=0; 27 % 7 " 6 

하지만 배율이 0이 아니면”정수 나머지 “를 제공하지 못합니다.

$ bc <<<" scale=10; 27 % 7 " .0000000003 

% 모듈로 정의가 왜 유용한가요?

답변

% 연산자는 분명히 bc 설명서 ( [a] ) :

# 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가 다음과 같이 정의되었다고 가정합니다.

define max(x,y){ if(x>y){return(x)};return(y) } 

이 긴 정의가 어떻게 유용합니까?

  1. 정수 나머지 .
    internalmod 함수와 % 연산자 결과가 다음 작업 중 일부에 대해 동일하다는 것을 증명합니다.

    숫자가 정수이고 스케일이 0으로 설정되면 정수 나머지 함수입니다.

    $ 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 

이것은 수학 모드 함수와 동일하지 않습니다. 아래에서 해결하겠습니다.

  1. 10 진수 나머지.
    숫자 n가 더 긴 십진수이고 배율을 수정하면 다음과 같은 결과가 나타납니다.

    $ 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 

    여기서는 처음 3 자리 10 진수가 제거되었고 나머지는 10 진수 4 자리에서 나온 것입니다.

    $ bc <<<"n=17.123456789;d=1; scale=7 ;a=internalmod(n,d,scale);b=n%d; print a," ",b,"\n"" .000000089 .000000089 

    그 나머지는 그 정의에 의해 더욱 다양해졌습니다.

현재 상태 : 나머지 이후 스케일 값.

  1. 스케일 변경 숫자 d (제수)가 n보다 더 많은 10 진수를 가질 수 있으므로 배율을 변경해야합니다.이 경우, 나눗셈에서 더 정확한 결과를 얻으려면 더 많은 소수가 필요합니다.

    $ 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 

    그리고 스케일이 변경되면 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 

    위에서 볼 수 있듯이 배율 값은 , dscale.

I” internalmod% 연산자 간의 비교를 통해 둘 다 동등한 것으로 입증되었다고 가정합니다.

  1. 혼란 . d의 값을 가지고 노는 것이 혼란 스러울 수 있으므로주의하세요.

    $ bc <<<"n=17.123456789; d=10; scale=3; a=n%d; print a," ",scale(a),"\n"" .003456789 9 

    그리고 :

    $ bc <<<"n=17.123456789; d=1000; scale=3; a=n%d; print a," ",scale(a),"\n"" .123456789 9 

    즉, d의 값 (1 이상)은 확장 집합 값의 효과를 수정합니다.

아마도 d의 값이 1과 다른 경우 scale = 0을 사용해야합니다 (현재 수행중인 작업을 실제로 알지 못하는 경우).

  1. 수학 모드 .
    mod 함수에 대해 자세히 살펴보면 bc에서 %의 실제 효과를 명확히해야 할 것입니다. BC의 % 연산자는 “절단 나누기”를 사용하고 있습니다. 0 방향으로 반올림하는 것입니다. 이는 n 및 / 또는 d 모두의 음수 값에 중요합니다.

    $ bc <<<"scale=0; n=13; d=7; n%d; " 6 $ bc <<<"scale=0; n=13; d=-7; n%d; " 6 

    나머지의 기호는 dividend의 기호를 따릅니다.

    $ bc <<<"scale=0; n=-13; d=7; n%d; " -6 $ bc <<<"scale=0; n=-13; d=-7; n%d; " -6 

    올바른 동안 math 모드는 항상 양의 나머지 를 제공해야합니다.

    (정수) 모드 기능을 얻으려면 다음을 사용하십시오.

    # 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)) } 

    그리고 (그런 다음) 작동합니다 :

    $ bc <<<"n=7.123456789; d=5; modeuclid(34.123456789,7)" 6.123456789 

[a]

expr % expr
표현식의 결과는 “나머지”이며 다음과 같이 계산됩니다. 방법. a % b를 계산하려면 먼저 a / b를 계산하여 숫자를 스케일링합니다.이 결과는 a- (a / b) * b를 scale + scale (b) 및 scale (a)의 최대 배율로 계산하는 데 사용됩니다.
scale이 0으로 설정되고 두식이 모두 정수이면이 식 정수 나머지 함수입니다.


이 각주 다음에 나오는 bc 코드의 경우 올바르게 작동하도록 도입되었으므로 별칭을 다음과 같이 정의하십시오.

$ alias bc="bc -l "$HOME/.func.bc"" 

그리고 ()를 포함하는 $HOME/.func.bc라는 파일을 만듭니다. 적어도) :

# 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)) } 

모든 숫자 (정수 여부)에 대한 mod 함수는 다음과 같이 정의 할 수 있습니다.

# 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) }; 

이 정의는 수학 규칙에 따라 완벽하게 유효하고 정확하지만 실제 사례에 적용하려고 할 때 매우 혼란 스러울 수 있습니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다