제곱근 단순화

제곱근 단순화

n주어진 정수에 대해 유형이 단순화된 제곱근을 설정 하는 명령을 만들고 싶습니다 n. 예를 들어,

\rsqrt{4}
\rsqrt{8}
\rsqrt{18}
\rsqrt{7}

의 그것과 같을 것이다

2
2\sqrt{2}
3\sqrt{2}
\sqrt{7}

\rsqrt{}문제의 명령은 어디에 있습니까?

나는 알고리즘이 다음과 같이 보일 것이라는 것을 알고 있습니다.

i = square root of n rounded down 

while i > 0:
    if n is divisible by i²:
        simplification is i\sqrt{n/i²}
        break loop
    i = i - 1

%the simpification will always be found
%since every n is divisible by 1

여기서 n는 주어진 정수이고, i는 이전의 숫자 \sqrt이고 n/i²는 의 인수입니다 \sqrt{...}.

하지만 라텍스에서 이것을 구현하는 방법을 모르겠습니다.

편집: 입력 숫자가 항상 정수임을 명확히 했습니다.

답변1

문제의 알고리즘은 매우 비효율적입니다. 물론 원래 정수가 완전 제곱인 경우는 제외됩니다.

이 답변(시간순)은 다음과 같습니다.

  1. 가장 간단한 인수분해 알고리즘을 모방한 매크로를 사용한 접근 방식,

  2. OP에서와 같이 알고리즘을 사용하는 확장 가능한 접근 방식입니다.업데이트매우 당황스럽게도 저자는 OP의 알고리즘을 이해하지 못했고 분할 I과 같은 단순화를 찾은 후 알고리즘이 거기서 멈출 수 있다는 것을 이해하지 못한 채 재귀적으로 하나를 진행했습니다 . (창백한 변명으로 그는 "하향식"(덜 효율적인) 방식과 반대로 재귀성이 필요한 "상향식" 방식을 먼저 구현했습니다.) 이에 따라 답변이 업데이트되었으며, 관대하고 신뢰하는 모든 조기 투표자들에게 사과드립니다.I^2NN<-N/I^2

    이제 의 문서를 더 많이 읽었고 효율성을 위해 에서 로 전환했기 때문에 다시 업데이트하고 있습니다(죄송합니다) . xintexpr.sty( 사용 가능한 것이 없으므로 마이너스 기호가 있는 트릭입니다.) 전자는 전체 숫자 목록( 에서 잘린 제곱근을 의미 )을 미리 생성하고, 후자는 미리 항목을 생성하지 않는 반복자입니다. 또한 이전 구문은 값에 대해서만 생성할 수 있습니다( 그런 제한은 없지만 여전히 모든 것을 미리 생성합니다).i=sqrt(N)..1i=-sqrt(N)++--floor(\sqrt{N})sqrt\xintiiexpr5000sqrt(N)..[-1]..1

  3. 접근 방식 1에서와 같이 더 빠른(고등학교 분해 유형) 알고리즘의 확장 가능한 구현입니다.

솔직히 말해서 2., 3., 심지어 1.은 아마도 약간 확장된 것 \numexpr보다 더 큰 숫자를 처리하는 척 하면서 완전히 작성하는 것이 더 나을 것입니다. 수만 개의 숫자를 처리하려면 10자리 소수로 시간이 걸립니다. 2^31나눗셈을 통해 제곱이 없다고 결론을 내릴 수 있습니다. 구현 2. 2^62제곱근은 TeX 숫자여야 하기 때문에(내부 구성으로 인해) 본질적인 한계가 있습니다.

\xintexpr2.와 3.에서는 재귀 시퀀스를 사용하여 구문 의 가능성을 합리적인 범위 이상으로 확장합니다 . 표기법이 좀 번거롭네요. 게다가 xintexpr.sty 1.2g관련 구문이 변경되었기 때문에 필요합니다.

  1. 마지막으로 (2017) 패키지 없는 numexpr 전용 확장형 접근 방식도 추가했습니다.

첫 번째 접근 방식(알고리즘 변경)

이것이 쉬운 문제라고 말할 수는 없습니다. 약간의 인터넷 검색을 통해 현재 수학자들이 정수의 제곱 자유 라디칼을 찾는 것이 완전한 인수분해만큼 어려울 수 있다고 믿고 있음이 드러났습니다.https://math.stackexchange.com/questions/171568/finding-the-radical-of-an-integer그리고https://math.stackexchange.com/questions/14667/square-free-integers-factorization.

다음은 가장 간단한 형태의 인수분해 알고리즘을 모방한 접근 방식(매크로 사용)입니다.

패키지는 표현식과 xintexpr같은 입력을 허용하기 위해서만 사용됩니다 . 1e7또한 xinttools구문에 사용되는 로드도 수행됩니다.

그 외에도 모든 작업은 에서 사용 가능한 매크로를 사용하여 수행됩니다 xint. 예제에서는 거의 숫자만 다루기 때문에 <2^31모든 작업이 고유를 사용하여 수행되는 변형을 사용할 수 있으며 \numexpr당연히 훨씬 더 빠릅니다.

\xintiiDivision몫과 나머지를 동시에 계산하는 코드를 사용합니다 . 이것이 \xintAssign두 개의 매크로 \A\B. 코드는 \Ba에 의한 분할 가능성을 감지하기 위해 사라지는 지 검사합니다 Q=P^2.

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}

\makeatletter
\def\Rsqrt@ {%
    \let\Nrad\N
    \def\Nroot {1}% 
% we will always have original N = \Nrad times \Nroot^2
% first we check powers of 2
    \def\P{2}%
    \def\Q{4}% \Q is always square of \P
    \xintloop
% try to divide \Nrad by 4. If possible, multiply \Nroot by 2
        \xintAssign\xintiiDivision{\Nrad}{\Q}\to \A\B
        \xintiiifZero{\B}
           {\let\Nrad\A
            \edef\Nroot{\xintiiMul{\Nroot}{\P}}% 
            \iftrue}
           {\iffalse}%
    \repeat
% try to divide \Nrad by 9=3^2, then by 25=5^2, etc...
% unfortunately we divide by all odd integers, but only odd prime
% integers would be really needed
    \def\P{3}%
    \xintloop
      \edef\Q{\xintiiSqr{\P}}%
      \xintiiifGt{\Q}{\Nrad}
         {\iffalse}%
         {\xintloop
             \xintAssign\xintiiDivision{\Nrad}{\Q}\to \A\B
             \xintiiifZero{\B}
                {\let\Nrad\A
                 \edef\Nroot{\xintiiMul{\P}{\Nroot}}% 
                 \iftrue}
                {\iffalse}%
          \repeat 
          \edef\P{\xintiiAdd{2}{\P}}%
          \iftrue
         }%
    \repeat
% at this stage \N = \Nrad times \Nroot^2
% and \Nrad is square-free.
    \xintiiifOne{\Nroot}{}{\Nroot}%
    \xintiiifOne{\Nrad} {}{\sqrt{\Nrad}}%
}%

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
}

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing
% \begin{multicols}{4}
% \xintFor* #1 in {\xintSeq {10000}{10100}}\do
%        {$\sqrt{#1}=\Rsqrt{#1}$\par}
% \end{multicols}

% $\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}, \Rsqrt{1e21}$

\pdfsetrandomseed 123456789

\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 1000)^2
             *\pdfuniformdeviate 1000\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<50
\repeat
\end{multicols}
    
\end{document}

여기에 이미지 설명을 입력하세요


두 번째 접근 방식(OP와 동일한 알고리즘, 확장 가능한 구현)

원래 알고리즘을 사용합니다. 여기서는 \ExtractRadical확장 가능하게 반환되는 항목을 A,B정의 합니다 N=A^2 B. 확장 불가능한 래퍼는 \Rsqrt위의 더 빠른 접근 방식에서 재활용하여 A\sqrt{B}부정 N또는 의 경우를 구별합니다 N=0, 1.

구현을 설명하기 위해 코드 주석을 추가했습니다. 이전 버전은 매우 형편없었고(답변 상단 참조) 추가로 필요했지만 xintexpr 1.2g더 이상 그렇지 않습니다.

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}

% Aim: given N find largest I such as I^2 divides N.
% Then compute J=N/I^2 and print I\sqrt{J}.

% Algorithm: compute first truncated square root Imax of N.
% With I = Imax try to divide N by I^2, if it does not work
% repeat with I replaced by I-1 and so on. 
% As soon as it works the seeked-for I has been found.

% **** Notice: embarrassingly the author of this answer initially continued
% **** the algorithm recursively with N<-N/I^2, which was very stupid, but
% **** explainable from the fact that he had implemented first another (much
% **** faster) algorithm which divided not from the top down, but from the
% **** bottom up.

% The code is far simpler now. And it does not require xintexpr 1.2g anymore,
% earlier versions of xintexpr.sty work, too.

% The iteration over i used Imax..1 syntax which requires Imax 
% to be <2^31. Else we could use Imax..[-1]..1, but we don't
% really consider realistic to iterate over 2^31 or more values !

% After an update we use (-Imax)++ syntax; this also requires Imax<2^31.

\def\ExtractRadical #1{%
  \xinttheiiexpr 
  subs(
  % we return I, #1//I^2 where I is biggest integer such as I^2 divides #1.
     (I, #1//I^2), 
  % The I is computed via the "seq" here. Theoretically this "seq" 
  % evaluates as many values as the last list indicates.
  % But here we omit all i's such that i^2 does not divide #1
  % and as soon as we have found one, we stop here and now by 
  % "break". We work topdown, at the worst I=1.
% The i=A..B syntax pre-generates all values, which is wasteful
% and limited to about at most 5000 values.
%       I=seq((#1/:i^2)?{omit}{break(i)}, i=sqrt(#1)..1)
% On the contrary the N++ syntax does not pre-generate anything.
       I=seq((#1/:i^2)?{omit}{break(-i)}, i=-sqrt(#1)++)
% There is currently no "n--" only "n++", thus we tricked with a minus sign.
      )
  \relax
}

\makeatletter

\def\Rsqrt@ {\expandafter\Rsqrt@@\romannumeral-`0\ExtractRadical\N,}

% The #2#3 trick is to get rid of a space after the comma
% because \ExtractRadical does \xinttheiiexpr which in case
% of comma separated values on output always inserts such a space.
% Naturally as the typesetting is in math mode the space is
% not a real problem (it is not a problem either in \xintiiifOne 
% as here its argument is already expanded anyhow).
\def\Rsqrt@@ #1,#2#3,{\xintiiifOne{#1}{}{#1}\xintiiifOne{#2#3}{}{\sqrt{#2#3}}}

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
 }

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing

\begin{multicols}{4}
\xintFor* #1 in {\xintSeq {10000}{10099}}\do
       {$\sqrt{#1}=\Rsqrt{#1}$\par}
\end{multicols}

% $\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}$%, 

% this one does not work because 10^10.5 > 2^31 causes an arithmetic
% overflow in the "sqrt(J)..1" part. 
% It would not overflow with "sqrt(J)..[-1]..1"
% but then we can wait long time ... 
% from 31622776601 downto
%      10000000000 that's a lot of iterations !
%$\Rsqrt{1e21}$
% The update uses n++ syntax, but this also requires abs(n) to be <2^31
% hence the same remark applies: a "Number too big" error is generated.
% Better actually than to wait the completion of 21622776601 iterations ;-)


% \stop

\pdfsetrandomseed 123456789

% we try with smaller numbers... 1000 replaced by 100...
\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 100)^2
             *\pdfuniformdeviate 100\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<51
\repeat
\end{multicols}

\end{document}

여기에 이미지 설명을 입력하세요


세 번째 접근 방식: 다시 한 번 더 빠른 알고리즘이지만 확장 가능합니다.

이것을 단품으로 코딩하는 것이 더 합리적일 것입니다 \numexpr. 코드 주석의 세부 사항. 이제 예제에는 51개의 무작위 예제가 있으며, 흥미롭게도 누락된 것(첫 번째 접근 방식에서)은 무작위 정사각형으로 판명되었습니다(pdftex 난수 생성기에 대한 무작위 시드가 에 설정되어 있음 123456789).

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}[2016/03/19]%
% needs xintexpr 1.2g due to 
%  - changed meaning of iter
%  - shift by 1 in [L][n] syntax


% syntax \ExtractRadical {N or <integer expression>} expands to "A, B" with
% N=A^2 B, B square-free
% Algorithm:
% main variable a triple (P, I, J) where
%  - always N = I^2 J
%  - J's prime factors < P have multiplicity one.
% START: (2, 1, N)
% ITER:  (P, I, J)
         % Q=P^2
         % is Q > J ?
         %   - yes: STOP(I, J)
         %   - no:
         %         does Q divide J ?
         %         - yes: I<-I*P, J<-J/Q and repeat until Q does not divide J
         %         - no; continue with (P+2, I, J). Except if P=2 then we go
         %                      on with P=3.
% Also works with N=0 (produces 1, 0) and with N=1 (produces 1, 1)
%

\newcommand*\ExtractRadical [1]{%
  \xinttheiiexpr 
  iter (2, 1, #1; % starting triple P=2, I=1, J=N
  subs(subs(subs(subs(
  % apart from Q=P^2, these substitutions are mainly because [@][n] syntax
  % is cumbersome; and inefficient as it allows n to be itself a complicated
  % expression, hence does some rather unneeded parsing here of n= 0, 1, 2.
  % We really need some better syntax like iter(P=2, I=1, J=#1;...) and then
  % work with P, I, J standing for the last values.
  % Or at least something like subs(..., (Q, P, I, J)=(...)).
  % (not yet with xintexpr 1.2g). 
  (Q>J)?
      {break(I, J)}
      {(J/:Q)?
          {(n)?{P+2}{3}, I, J}
      % must use parentheses here: ([@][1]). Else ]/: will confuse parser.
      % I could have used again subs, but well. 
          {iter(P*I,J//Q;(([@][1])/:Q)?{break((n)?{P+2}{3},@)}
                                       {(P*[@][0],([@][1])//Q)},e=1++)
          }
      }
  , Q=P^2), P=[@][0]), I=[@][1]), J=[@][2]), n=0++)
    \relax
}             
                  
\makeatletter
\def\Rsqrt@ {\expandafter\Rsqrt@@\romannumeral-`0\ExtractRadical\N,}

\def\Rsqrt@@ #1,#2,{\xintiiifOne{#1}{}{#1}\xintiiifOne{#2}{}{\sqrt{#2}}}

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
 }

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing

% \xintFor* #1 in {\xintSeq {0}{50}}\do 
% {\ExtractRadical {#1}\par}

% \ExtractRadical {128}

% \ExtractRadical {1024}
% \stop

% $\Rsqrt{5000}$

% \stop

% \begin{multicols}{4}
% \xintFor* #1 in {\xintSeq {10000}{10099}}\do
%        {$\sqrt{#1}=\Rsqrt{#1}$\par}
% \end{multicols}

$\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}, \Rsqrt {1e21}$%, 

\pdfsetrandomseed 123456789

\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 1000)^2
             *\pdfuniformdeviate 1000\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<51
\repeat
\end{multicols}

\end{document}

여기에 이미지 설명을 입력하세요


업데이트(2017).

필요한 경우 패키지 없이 확장 가능한 매크로가 있습니다. 원본이 있는 I,J곳 으로 확장되며 사각형 이 없습니다. 만 사용합니다 . 정수 로 제한됩니다 . 기본 인수분해 방법과 동일하게 낮은 것부터 큰 것까지 작동합니다. 중지 기준이 개선되어야 합니다. 아래 설명은 여기에도 적용됩니다.NI**2 times JJ\numexpr<2**31

\makeatletter

\newcommand\ExtractRadical[1]{%
    \romannumeral0%
    \expandafter
    \ExtractRadical@two@i\expandafter1\expandafter,\the\numexpr#1.%
}%
\def\ExtractRadical@two@i #1,#2.{%
    \ifnum4>#2 \expandafter\ExtractRadical@two@done\fi
    \expandafter\ExtractRadical@two@ii\the\numexpr#2/4;#1,#2.%
}%
\edef\ExtractRadical@two@done #1;#2,#3.%
    {\space#2,#3}% (not sole #2 for readability)
\def\ExtractRadical@two@ii #1;#2,#3.{%
    \ifnum\numexpr#1*4=#3 
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
   {\expandafter\ExtractRadical@two@i\the\numexpr2*#2,#1.}%
   {\ExtractRadical@i 3;#2,#3.}%
}%
\def\ExtractRadical@i #1;{%
    \expandafter\ExtractRadical@ii\the\numexpr#1*#1.#1;%
}%
\def\ExtractRadical@ii #1.#2;#3,#4.{%
    \ifnum#1>#4 \expandafter\ExtractRadical@done\fi
    \expandafter\ExtractRadical@iii\the\numexpr#4/#1.#1;#4.#2;#3.%
}%
\def\ExtractRadical@iii #1.#2;#3.{%
    \ifnum\numexpr#1*#2=#3
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    \ExtractRadical@update
    \ExtractRadical@next
    #1.#2;#3.%
}%
\def\ExtractRadical@update #1.#2;#3.#4;#5.{%
    \expandafter\ExtractRadical@ii
    \the\numexpr#2\expandafter.%
    \the\numexpr#4\expandafter;%
    \the\numexpr#4*#5,#1.%
}%
\def\ExtractRadical@next #1.#2;#3.#4;#5.{%
    \expandafter\ExtractRadical@i\the\numexpr2+#4;#5,#3.%
}%
\edef\ExtractRadical@done #1;#2.#3;#4.{\space#4,#2}%

\makeatother

답변2

LuaLaTeX 기반 솔루션은 다음과 같습니다. 코드는 라는 \rsqrtLua 함수를 호출하는 LaTeX 매크로를 설정합니다 rsqrt. 후자는 제안한 단순화 알고리즘을 다음과 같이 개선하여 구현합니다.

  • n=0또는 의 경우 n=1코드는 단순히 반환합니다 n(제곱근 기호 없이). 그리고

  • \sqrt{n/i²}와 같은 경우 1, 즉 n"제곱수"(4, 9, 16 등)이거나 더 작은 제곱수의 곱인 경우 용어를 생략하도록 주의해야 합니다 . 예를 들어, if 는 n=36이후 를 \rsqrt{36}표시합니다 .636 = 6^2 = 2^2*3^2

입력 온전성 검사는 수행되지 않습니다. 즉, 사용자는 \rsqrt음수가 아닌 정수이거나 음수가 아닌 정수로 평가되는 인수를 제공할 책임이 있습니다. 따라서 \rsqrt{1e6}및 : 을 작성해도 괜찮습니다 \rsqrt{3.6e7}. 매크로는 각각 1000및 를 반환합니다 6000.

매크로는 지시문을 \rsqrt출력할 수 있으므로 수학 모드에서 사용해야 합니다 \sqrt.

여기에 이미지 설명을 입력하세요

% !TEX TS-program = lualatex  
%% Note: Code updated 2019/10/26 to work with LaTeX 2019-10-01 

%% Create an external file to contain the Lua code
\begin{filecontents*}[overwrite]{rsqrt.lua}
function rsqrt ( n )
  -- n : a non-negative whole number (or something
  --     that evaluates to a non-neg. whole number)
  if n == 0 or n == 1 then   -- Nothing to do
    return ( n )
  else
    i = math.floor ( math.sqrt ( n ) )
    while i > 1 do
      if ( n % i^2 == 0 ) then     -- n is divisible by i^2
        k = math.floor ( n / i^2 ) -- 'math.floor' makes k an explicit integer
        if k == 1 then  -- n is a "square" number (or a product of square numbers)
          return ( i )
        else
          return ( i .. "\\sqrt{" .. k .. "}" )
        end
      end
      i = i-1
    end
    -- No simplification possible:
    return ( "\\sqrt{" .. n .. "}" )
  end
end
-- Define a vector (in form of a Lua table) of whole numbers
nvec = {0,1,2,3,4,5,7,12,16,18,27,32}

-- Lua function to print 3-column array:
function PrintArray()
  for i=1,#nvec do
    u = nvec[i]
    tex.sprint ( math.floor(u) .. 
                "& \\sqrt{" .. math.floor(u) .. 
                "}&" .. rsqrt(u) .. "\\\\" )
  end
end
\end{filecontents*}

\documentclass{article}

%% Load Lua code from external file:
\directlua{dofile("rsqrt.lua")}

%% TeX-side code: "wrapper" macro that invokes the Lua function:
\newcommand\rsqrt[1]{\directlua{tex.sprint(rsqrt(#1))}}

\begin{document}
\[
\renewcommand\arraystretch{1.25}
\begin{array}{@{} rcc @{}}
  \verb+n+ & \verb+\sqrt+ & \verb+\rsqrt+ \\ % print header row
  \directlua{PrintArray()}    % create and print body of 'array'
\end{array}
\]
\end{document} 

답변3

안에 expl3:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\rsqrt}{m}
 {
  \manual_rsqrt:n { #1 }
 }

\int_new:N \l_manual_rsqrt_int

\cs_new_protected:Nn \manual_rsqrt:n
 {
  \int_set:Nn \l_manual_rsqrt_int { \fp_to_decimal:n { trunc(sqrt(#1),0) } }
  \bool_until_do:nn
   {
    \int_compare_p:n { \int_mod:nn { #1 } { \l_manual_rsqrt_int * \l_manual_rsqrt_int } == 0 }
   }
   {
    \int_decr:N \l_manual_rsqrt_int
   }
  \int_compare:nTF { \l_manual_rsqrt_int == 1 }
   {
    \sqrt{#1}
   }
   {
    \int_to_arabic:n { \l_manual_rsqrt_int }
    \int_compare:nF { #1 == \l_manual_rsqrt_int*\l_manual_rsqrt_int }
     {
      \sqrt{ \int_to_arabic:n { #1/(\l_manual_rsqrt_int*\l_manual_rsqrt_int) } }
     }
   }
 }
\ExplSyntaxOff

\begin{document}

$\rsqrt{4}$

$\rsqrt{8}$

$\rsqrt{18}$

$\rsqrt{12}$

$\rsqrt{7}$

\end{document}

여기에 이미지 설명을 입력하세요

인수 0과 1 및 부정 인수도 처리하려면 기본 정의를 다음으로 변경할 수 있습니다.

\NewDocumentCommand{\rsqrt}{m}
 {
  \int_compare:nTF { #1 < 0 }
   {
    \int_compare:nTF { #1 = -1 } { i } { \manual_rsqrt:n { -#1 } i }
   }
   {
    \int_compare:nTF { #1 < 2 } { #1 } { \manual_rsqrt:n { #1 } }
   }
 }

이제 입력

$\rsqrt{0}$ and $\rsqrt{1}$

$\rsqrt{-1}$ and $\rsqrt{-4}$ and $\rsqrt{-32}$

출력할 것이다

여기에 이미지 설명을 입력하세요

답변4

LaTeX 외부로 나가는 것을 싫어하지 않는다면 pythontex패키지를 사용하는 솔루션이 있습니다. 나는 그것을 sroot단순한 루트라고 불렀습니다. 물론, 원하는 대로 부를 수 있습니다. 이 버전에는

pdflatex *filename*.tex, pythontex filename*.tex, pdflatex *filename*.tex문서의 실행 순서입니다.

\documentclass{article}
\usepackage{pythontex}
\begin{document}
\newcommand{\sroot}[1]{\ensuremath{\py{simpleroot(#1)}}}
\begin{pycode}
from math import *
def simpleroot(n):
    if n==0:
        return(str(0))
    j=int(sqrt(n))
    flag_continue=True
    while flag_continue:
        b=n*1./(j*j)
        if b==int(b):
            mystring=str(j)+'\\sqrt{'+str(int(b)) +'}'
            flag_continue=False
        else:
            j-=1

        if int(b)==1:
            mystring=str(j)
        if int(b)==n and b>1:
            mystring='\\sqrt{'+str(int(b)) +'}'

    return(mystring)
\end{pycode}

This is a test.

The $\sqrt{1}$ is \sroot{1}.

The $\sqrt{4}$ is \sroot{4}.

The $\sqrt{7}$ is \sroot{7}.

The $\sqrt{8}$ is \sroot{8}.

The $\sqrt{18}$ is \sroot{18}.

The $\sqrt{23}$ is \sroot{23}.

The $\sqrt{27}$ is \sroot{27}.

The $\sqrt{32}$ is \sroot{32}.

The $\sqrt{64}$ is \sroot{64}.

The $\sqrt{80}$ is \sroot{80}.

The $\sqrt{1000}$ is \sroot{1000}.

The $\sqrt{3000033}$ is \sroot{3000033}.

Goodbye.
\end{document}

관련 정보