이것은 자체 답변 질문입니다. 질문을하기에 합당한 조사는 답변 부분에 있습니다. 제가 답변을 충분히 조사하지 않았다고 생각하므로 반대표를 던지지 마십시오. 감사. 어쨌든이 사이트에는 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) }
이 긴 정의가 어떻게 유용합니까?
-
정수 나머지 .
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
이것은 수학 모드 함수와 동일하지 않습니다. 아래에서 해결하겠습니다.
-
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
그 나머지는 그 정의에 의해 더욱 다양해졌습니다.
현재 상태 : 나머지 이후 스케일 값.
-
스케일 변경 숫자
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
위에서 볼 수 있듯이 배율 값은 ,
d
및scale
.
I” internalmod
와 %
연산자 간의 비교를 통해 둘 다 동등한 것으로 입증되었다고 가정합니다.
-
혼란 .
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을 사용해야합니다 (현재 수행중인 작업을 실제로 알지 못하는 경우).
-
수학 모드 .
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) };
이 정의는 수학 규칙에 따라 완벽하게 유효하고 정확하지만 실제 사례에 적용하려고 할 때 매우 혼란 스러울 수 있습니다.