
Quiero crear un comando que, para un número entero dado n
, escriba una raíz cuadrada simplificada de n
. Por ejemplo, la salida de
\rsqrt{4}
\rsqrt{8}
\rsqrt{18}
\rsqrt{7}
sería el mismo que el de
2
2\sqrt{2}
3\sqrt{2}
\sqrt{7}
¿Dónde \rsqrt{}
está el comando en cuestión?
Sé que el algoritmo se parecería a esto
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
donde n
es el número entero dado, i
es el número anterior \sqrt
y n/i²
es el argumento de \sqrt{...}
.
¿Pero no tengo idea de cómo implementar esto en látex?
EDITAR: Se aclaró que el número de entrada siempre será un número entero.
Respuesta1
El algoritmo de la pregunta es muy ineficiente: excepto, por supuesto, si el número entero original es un cuadrado perfecto.
Esta respuesta (en orden cronológico):
un enfoque con macros que imita el algoritmo de factorización más simple,
un enfoque ampliable utilizando el algoritmo como en OP.actualizarMuy vergonzosamente, el autor no había entendido el algoritmo del OP y después de haber encontrado una simplificación
I
comoI^2
divididaN
, fue recursivamente sinN<-N/I^2
entender que el algoritmo podía detenerse allí. (como excusa, había implementado primero el método "de abajo hacia arriba", que necesita recursividad, al contrario del método "de arriba hacia abajo" (menos eficiente)). La respuesta se actualiza así, disculpas a todos los generosos y confiados primeros votantes.Estoy actualizando nuevamente (lo siento) porque ahora leí más
xintexpr.sty
documentación de y cambié por eficiencia dei=sqrt(N)..1
ai=-sqrt(N)++
(no hay ninguna--
disponible, de ahí un truco con signo menos). El primero genera de antemano la lista completa defloor(\sqrt{N})
números (sqrt
significa raíz cuadrada truncada\xintiiexpr
), el segundo es un iterador que no genera cosas de antemano. Además, la sintaxis anterior solo puede generar5000
valores aproximados (sqrt(N)..[-1]..1
no tendría tal limitación, pero aún así generaría todo de antemano).una implementación ampliable de un algoritmo más rápido (tipo de factorización de escuela secundaria) como en el enfoque 1.
Para ser honesto, 2., 3. e incluso 1. probablemente estarían mejor escritos en su totalidad usando \numexpr
como pretensión de manejar números más grandes que 2^31
lo que es un poco exagerado, se necesita tiempo con un número primo de 10 dígitos para hacer decenas de miles de divisiones para concluir que no tenía cuadrados... La implementación 2. tiene un límite intrínseco porque 2^62
la raíz cuadrada debe ser un número TeX (debido a alguna construcción interna).
En 2. y 3., llevamos un poco más allá de lo razonable las posibilidades de \xintexpr
sintaxis con secuencias recursivas. La notación es un poco engorrosa. Además xintexpr.sty 1.2g
es necesario porque cambió la sintaxis relevante.
- finalmente (2017) también agrego el enfoque expandible sin paquete numexpr.
Primer enfoque (cambiamos el algoritmo)
No quiere decir que éste sea un problema fácil. Un poco de búsqueda en Google revela que aparentemente los matemáticos creen actualmente que encontrar el radical libre cuadrado de un número entero puede ser tan difícil como una factorización completa:https://math.stackexchange.com/questions/171568/finding-the-radical-of-an-integeryhttps://math.stackexchange.com/questions/14667/square-free-integers-factorization.
Aquí hay un enfoque (usando macros) que imita la forma más simple de algoritmo de factorización.
El paquete xintexpr
se utiliza sólo para permitir entradas como 1e7
o incluso expresiones. También carga xinttools
cuál se utiliza en la sintaxis.
Aparte de eso, todas las operaciones se realizan con macros disponibles en xint
. Como en el ejemplo tratamos casi solo con números, <2^31
podríamos emplear una variante en la que todas las operaciones se realizarían utilizando de forma única \numexpr
, naturalmente, eso sería bastante más rápido.
El código utiliza \xintiiDivision
el cual calcula simultáneamente el cociente y el resto. Por eso \xintAssign
se utiliza para almacenarlos en dos macros \A
y \B
. El código examina si \B
desaparece para detectar la divisibilidad por 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}
Segundo enfoque (mismo algoritmo que en OP, implementación ampliable)
Con el algoritmo original. Aquí definimos \ExtractRadical
cuál regresa expandiblemente A,B
con N=A^2 B
. Un envoltorio no expandible se recicla \Rsqrt
desde el enfoque más rápido anterior para producir A\sqrt{B}
, distinguiendo casos de negativo N
o N=0, 1
.
He agregado comentarios de código para explicar la implementación. Una versión anterior era muy aburrida (ver la parte superior de la respuesta) y además requería xintexpr 1.2g
lo que ya no es el caso.
\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}
Tercer enfoque: nuevamente el algoritmo más rápido, pero expandible.
Sería más razonable codificar esto à la \numexpr
pero bien. Detalles en el comentario del código. El ejemplo ahora tiene 51 ejemplos aleatorios y, curiosamente, el que faltaba (desde el primer enfoque) resultó ser un cuadrado aleatorio (con la semilla aleatoria del generador de números aleatorios pdftex configurada en 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}
Actualización (2017).
Aquí hay una macro expandible sin paquete, si es necesario. Se expande hasta I,J
donde N
está el original I**2 times J
y J
no tiene cuadrados. Solo usos \numexpr
. Limitado a <2**31
números enteros. Funciona de menor a mayor, igual que el método de factorización elemental. Los criterios de parada deberían mejorarse; el siguiente comentario también se aplica aquí.
\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
Respuesta2
Aquí hay una solución basada en LuaLaTeX. El código configura una macro LaTeX llamada \rsqrt
, que invoca una función Lua llamada rsqrt
. Este último implementa el algoritmo de simplificación que usted propuso, con las siguientes mejoras:
Para
n=0
on=1
, el código simplemente devuelven
(sin símbolo de raíz cuadrada); ySe tiene cuidado de omitir el
\sqrt{n/i²}
término si es igual a1
, es decir, sin
es un "número cuadrado" (4, 9, 16, etc.) o un producto de números cuadrados más pequeños. Por ejemplon=36
, si\rsqrt{36}
muestra6
desde36 = 6^2 = 2^2*3^2
.
No se realiza ninguna verificación de validez de la entrada, es decir, el usuario es responsable de proporcionar un argumento \rsqrt
que sea un número entero no negativo o que se evalúe como un número entero no negativo. Por lo tanto, está bien escribir \rsqrt{1e6}
y \rsqrt{3.6e7}
: la macro devolverá 1000
y 6000
, respectivamente.
Observe que la macro \rsqrt
debe usarse en modo matemático ya que puede generar \sqrt
directivas.
% !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}
Respuesta3
En 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}
Si desea tratar con los argumentos 0 y 1 y también con argumentos negativos, puede cambiar la definición principal a
\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 } }
}
}
Ahora la entrada
$\rsqrt{0}$ and $\rsqrt{1}$
$\rsqrt{-1}$ and $\rsqrt{-4}$ and $\rsqrt{-32}$
daría salida
Respuesta4
Si no es reacio a saltar fuera de LaTeX, aquí tiene una solución que utiliza el pythontex
paquete. Lo llamé sroot
raíz simple. Obviamente, puedes llamarlo como quieras. Esta versión requiere un
pdflatex *filename*.tex
,
pythontex filename*.tex
,
pdflatex *filename*.tex
secuencia de ejecución de su documento.
\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}