
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
문제의 알고리즘은 매우 비효율적입니다. 물론 원래 정수가 완전 제곱인 경우는 제외됩니다.
이 답변(시간순)은 다음과 같습니다.
가장 간단한 인수분해 알고리즘을 모방한 매크로를 사용한 접근 방식,
OP에서와 같이 알고리즘을 사용하는 확장 가능한 접근 방식입니다.업데이트매우 당황스럽게도 저자는 OP의 알고리즘을 이해하지 못했고 분할
I
과 같은 단순화를 찾은 후 알고리즘이 거기서 멈출 수 있다는 것을 이해하지 못한 채 재귀적으로 하나를 진행했습니다 . (창백한 변명으로 그는 "하향식"(덜 효율적인) 방식과 반대로 재귀성이 필요한 "상향식" 방식을 먼저 구현했습니다.) 이에 따라 답변이 업데이트되었으며, 관대하고 신뢰하는 모든 조기 투표자들에게 사과드립니다.I^2
N
N<-N/I^2
이제 의 문서를 더 많이 읽었고 효율성을 위해 에서 로 전환했기 때문에 다시 업데이트하고 있습니다(죄송합니다) .
xintexpr.sty
( 사용 가능한 것이 없으므로 마이너스 기호가 있는 트릭입니다.) 전자는 전체 숫자 목록( 에서 잘린 제곱근을 의미 )을 미리 생성하고, 후자는 미리 항목을 생성하지 않는 반복자입니다. 또한 이전 구문은 값에 대해서만 생성할 수 있습니다( 그런 제한은 없지만 여전히 모든 것을 미리 생성합니다).i=sqrt(N)..1
i=-sqrt(N)++
--
floor(\sqrt{N})
sqrt
\xintiiexpr
5000
sqrt(N)..[-1]..1
접근 방식 1에서와 같이 더 빠른(고등학교 분해 유형) 알고리즘의 확장 가능한 구현입니다.
솔직히 말해서 2., 3., 심지어 1.은 아마도 약간 확장된 것 \numexpr
보다 더 큰 숫자를 처리하는 척 하면서 완전히 작성하는 것이 더 나을 것입니다. 수만 개의 숫자를 처리하려면 10자리 소수로 시간이 걸립니다. 2^31
나눗셈을 통해 제곱이 없다고 결론을 내릴 수 있습니다. 구현 2. 2^62
제곱근은 TeX 숫자여야 하기 때문에(내부 구성으로 인해) 본질적인 한계가 있습니다.
\xintexpr
2.와 3.에서는 재귀 시퀀스를 사용하여 구문 의 가능성을 합리적인 범위 이상으로 확장합니다 . 표기법이 좀 번거롭네요. 게다가 xintexpr.sty 1.2g
관련 구문이 변경되었기 때문에 필요합니다.
- 마지막으로 (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
. 코드는 \B
a에 의한 분할 가능성을 감지하기 위해 사라지는 지 검사합니다 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
곳 으로 확장되며 사각형 이 없습니다. 만 사용합니다 . 정수 로 제한됩니다 . 기본 인수분해 방법과 동일하게 낮은 것부터 큰 것까지 작동합니다. 중지 기준이 개선되어야 합니다. 아래 설명은 여기에도 적용됩니다.N
I**2 times J
J
\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 기반 솔루션은 다음과 같습니다. 코드는 라는 \rsqrt
Lua 함수를 호출하는 LaTeX 매크로를 설정합니다 rsqrt
. 후자는 제안한 단순화 알고리즘을 다음과 같이 개선하여 구현합니다.
n=0
또는 의 경우n=1
코드는 단순히 반환합니다n
(제곱근 기호 없이). 그리고\sqrt{n/i²}
와 같은 경우1
, 즉n
"제곱수"(4, 9, 16 등)이거나 더 작은 제곱수의 곱인 경우 용어를 생략하도록 주의해야 합니다 . 예를 들어, if 는n=36
이후 를\rsqrt{36}
표시합니다 .6
36 = 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}