이렇게 긴 정의가 무슨 소용이 있나요?

이렇게 긴 정의가 무슨 소용이 있나요?

이것은스스로에게 답해보세요질문, 질문을 하는 합리적인 연구는 답변 섹션에 담겨 있습니다. 답변에 대한 조사가 충분하지 않다고 생각하므로 비추천하지 마십시오. 감사해요. 어쨌든, 이 웹사이트에는 bc의 이 기능에 대한 설명이 없습니다.

bc이 연산자는 사용될 때 "나머지"를 계산한다고 주장합니다 %. 예, 정수와 함께 작동합니다.규모가 0이다:

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

그러나 소수 자릿수가 0이 아닌 경우 "정수 나머지"를 제공할 수 없습니다.

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

이 모듈 정의가 왜(또는 어떻게) %유용한가요?

답변1

운영자님이 %아주 명확하게 말씀해주셨네요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다음과 같이 정의되었다고 가정합니다 .

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
    

이는 수학 mod 기능과 다릅니다. 이에 대해서는 아래에서 다루겠습니다.

  1. 소수 나머지.
    숫자가 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자리가 제거되고 나머지는 소수점 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. 이 경우 더 정확한 나누기 결과를 얻으려면 더 많은 소수가 필요합니다.

    $ 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
    

    그리고 규모가 변경되면:

    $ 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
    

    n위에서 볼 수 있듯이, d, 및 의 모든 값에 대해 스케일 값이 변경되어 상당히 정확한 나눗셈 결과를 렌더링합니다 scale.

나는 두 연산자가 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 함수를 탐구하고 있으므로 %in 의 실제 효과를 명확히 해야 할 것입니다 bc. bc의 연산자는 %"잘린 나눗셈"을 사용합니다. 반올림 방향 0. 이는 nand/or의 음수 값에 중요합니다 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
    

    비록 정확하지만수학모듈은 다음을 제공해야 합니다.나머지는 항상 긍정적이다.

    (정수) mod 함수를 얻으려면 다음을 사용하십시오.

    # 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
    

[ㅏ]

expr %
expr 표현식의 결과는 "나머지"이며 다음과 같이 계산됩니다. a%b를 계산하려면 먼저 a/b를 계산하여 숫자의 크기를 조정하세요. 이 결과는 scale+scale(b)와 scale(a)의 최대 비율로 a-(a/b)*b를 계산하는 데 사용됩니다.
척도가 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) };

수학의 규칙에 따르면 이 정의는 완벽하게 타당하고 정확하지만, 이를 실제 상황에 적용하려고 하면 상당히 혼란스러울 수 있습니다.

답변2

BC와 해당 연산자에 대한 설명은 POSIX 표준의 일부입니다. 현재 위치는 다음과 같습니다.

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

a % b는 a - (a / b) * b로 정의되고 max(scale + scale(b), scale(a))로 계산됩니다.

현재 버전 1.07.1 기준으로 GNU BC의 경우입니다. BSD의 경우 BC는 단지 DC의 껍질일 뿐이고, DC는 "%"를 나타내기 위해 "bn"을 사용합니다.

C-BC에서도 마찬가지이다. C-BC, 그 출처는 여기에 보관되어 있습니다:

https://github.com/RockBrentwood/CBC

BC의 대규모 확장이며 C에 더 가깝고 (주로) GNU BC 및 BSD BC의 상위 집합입니다.

관련 정보