为什么我的减号后面会出现这个奇怪的空格

为什么我的减号后面会出现这个奇怪的空格

我正在使用 MathJax-Node 将 TeX 数学方程式转换为 MathML 和 SVG。大部分情况下,这都很好用。但当我渲染塔珀的自我参照公式,指数中的第二个减号后面出现了一个奇怪的空格:渲染公式

该空间还出现在数学网址(上图就是由此而来的)。当我检查生成的 MathML 时,我可以看到 MathJax 明确插入了一个mspace元素。

我使用的 TeX 如下:

\frac12<\left\lfloor\mod\left(\left\lfloor\frac y{17}\right\rfloor2^{{-17}\left\lfloor x\right\rfloor-\mod\left(\left\lfloor y\right\rfloor,17\right)},2\right)\right\rfloor

知道这里发生什么事了吗?

答案1

您使用“mod”作为数学运算符,如“exp”或“sin”。该命令\mod用于表示法,例如

5 \equiv 2 \mod{3}

并且这里显然需要插入空格。

改用\operatorname{mod}

\documentclass{article}
\usepackage{amsmath}

\begin{document}

\[
\frac{1}{2}<
  \left\lfloor
    \operatorname{mod}\left(
      \left\lfloor\frac{y}{17}\right\rfloor
      2^{-17\lfloor x\rfloor-\operatorname{mod}(\lfloor y\rfloor,17)},2
    \right)
  \right\rfloor
\]

\end{document}

我已经删除了无用的(和错误的)\left\right对。

在此处输入图片描述

它在 MathJax 中同样有效(在 Math.SE 上测试):

在此处输入图片描述

答案2

你的意思是:

在此处输入图片描述

\documentclass{article}

\usepackage{xintexpr}

% Tupper

% q = floor(y/17)
% r = mod(y, 17)   (modulo for floor)

% Tupper formula boils down to say:

% Pixel (x, y) is ON <===> floor(q, 2**(17x+r)) is ODD

% https://fr.wikipedia.org/wiki/Formule_autor%C3%A9f%C3%A9rente_de_Tupper

% \xintiiexpr notations

% floored division is //
% associated modulo is /: (or 'mod')
% divmod(,) is both // and /: (as in Python)

\begin{document}

% 0 <= x < 106
% k <= y < k + 17

\xintdefiivar TupperK := 
960939379918958884971672962127852754715004339660129306651505519271702802395266
424689642842174350718121267153782770623355993237280874144307891325963941337723
487857735749823926629715517173716995165232890538221612403238855866184013235585
136048828693337902491454229288667081096184496091705183454067827731551705405381
627380967602565625016981482083418783163849115590225610003652351370343874461848
378737238198224849863465033159410054974700593138339226497249461751545728366702
369745461014655997933798537483143786841806593422227898388722980000748404719;

\setlength\unitlength{1pt}

\def\parseTupperXY#1#2{% #1 = x, #2=y, 
    \xintdefiivar Yq, Yr = divmod(#2, 17);%
    \edef\resultTupperXY{\xinttheiiexpr odd(Yq // 2**(17 * #1 + Yr))\relax}%
}%

% This is a bit slow, be patient (big powers of 2 are computed...)
% Much faster would be to convert TupperK to binary...
\begin{picture}(106,17)
  \xintFor* #1 in {\xintSeq{0}{105}}\do {% x
      \xintFor* #2 in {\xintSeq{0}{16}}\do {%  y - k
          \parseTupperXY{#1}{#2+TupperK}
          \if1\resultTupperXY
             \put(\numexpr105-#1, \numexpr16-#2){\rule{1pt}{1pt}}
          \fi
      }
  }
\end{picture}

\end{document}

我希望这

\documentclass{article}

\usepackage{xintexpr}

% Tupper

% q = floor(y/17)
% r = mod(y, 17)   (modulo for floor)

% Tupper formula boils down to say:

% Pixel (x, y) is ON <===> floor(q, 2**(17x+r)) is ODD

% https://fr.wikipedia.org/wiki/Formule_autor%C3%A9f%C3%A9rente_de_Tupper

% \xintiiexpr notations

% floored division is //
% associated modulo is /: (or 'mod')
% divmod(,) is both // and /: (as in Python)

\begin{document}

% 0 <= x < 106
% k <= y < k + 17

\xintdefiivar TupperK := 
960939379918958884971672962127852754715004339660129306651505519271702802395266
424689642842174350718121267153782770623355993237280874144307891325963941337723
487857735749823926629715517173716995165232890538221612403238855866184013235585
136048828693337902491454229288667081096184496091705183454067827731551705405381
627380967602565625016981482083418783163849115590225610003652351370343874461848
378737238198224849863465033159410054974700593138339226497249461751545728366702
369745461014655997933798537483143786841806593422227898388722980000748404719;

\setlength\unitlength{1pt}

\xintdefiivar twoToThe17 := 2**17;
\xintdefiivar twoToThe17timesX := 1;

\begin{picture}(106,17)
  \xintFor* #1 in {\xintSeq{0}{105}}\do {% x
      \xintFor* #2 in {0123456789{10}{11}{12}{13}{14}{15}{16}}\do {%  y - k
          \xintdefiivar Yq, Yr = divmod(#2 + TupperK, 17);%
          \xintifbooliiexpr {odd(Yq // (twoToThe17timesX * 2**Yr ))}
             {\put(\numexpr105-#1, \numexpr16-#2){\rule{1pt}{1pt}}}
             {}
      }
   \xintdefiivar twoToThe17timesX := twoToThe17 * twoToThe17timesX;%
  }
\end{picture}

\end{document}

会更快,但只是快了一点点。因此瓶颈在于大的除法,而不是 2 的幂。

例如,稍微作弊并计算kvia的二进制表示形式会更快。\xintDecToBinxintbinhex


使用实数公式计算像素

上面的内容有点作弊:实际使用的确定像素是否为 ON 的公式与原始公式略有不同,因为它仅使用整数算法。当然,可以使用\xintexpr而不是\xintiiexpr并执行“实际”操作……当然,这会慢一点。(仍然)

\documentclass{article}

\usepackage{xintexpr}

% Tupper

% q = floor(y/17)
% r = mod(y, 17)   (modulo for floor)

% Tupper formula is (exactly) (apart from using floor rather than ⌊ and ⌋)

% Pixel (x, y) is ON <===> 1/2 < floor(mod(floor(y/17)2**(-17x-mod(y, 17)), 2))

% The latter means floor(q, 2**(17x+r)) is ODD, when using only
% integers
% but here we will be using the REAL THING !


\begin{document}

% 0 <= x < 106
% k <= y < k + 17

\xintdefiivar TupperK := 
960939379918958884971672962127852754715004339660129306651505519271702802395266
424689642842174350718121267153782770623355993237280874144307891325963941337723
487857735749823926629715517173716995165232890538221612403238855866184013235585
136048828693337902491454229288667081096184496091705183454067827731551705405381
627380967602565625016981482083418783163849115590225610003652351370343874461848
378737238198224849863465033159410054974700593138339226497249461751545728366702
369745461014655997933798537483143786841806593422227898388722980000748404719;

\setlength\unitlength{1pt}

% SLOW ! (about 55s on 2.4Ghz laptop)

\begin{picture}(106,17)
  \xintFor* #1 in {\xintSeq{0}{105}}\do {% x
          \xintdefiivar x = #1;% to let the formula use X, Y, not #1, #2
      \xintFor* #2 in {0123456789{10}{11}{12}{13}{14}{15}{16}}\do {%  y - k
          \xintdefiivar y = #2 + TupperK;%
          \xintifboolexpr 
% TUPPER FORMULA USED AS INPUT SHOWS IN OUTPUT
% EXCEPT WE USE floor NOT ⌊, ⌋ AS THIS IS XINTEXPR SYNTAX
          {1/2 < floor(mod(floor(y/17)2**(-17x-mod(y, 17)), 2))}
             {\put(\numexpr105-#1, \numexpr16-#2){\rule{1pt}{1pt}}}
             {}
      }
  }
\end{picture}

\end{document}

通过二进制数字作弊,更快地构建图片

在另一个方向上,我们可以完全作弊,对k/17原始公式进行分析,将其转换为二进制数字,即当某位为 1 时,像素为开。自然,图像的生成速度会更快。

\documentclass{article}

\usepackage{xintexpr}

% Tupper

% q = floor(y/17)
% r = mod(y, 17)

% Tupper formula boils down to say:

% Pixel (x, y) is ON <===> floor(q / 2**(17x+r)) is ODD

% https://fr.wikipedia.org/wiki/Formule_autor%C3%A9f%C3%A9rente_de_Tupper

% This also means that

% Pixel (x, y) is ON <==> 17x+r bit of q is 1

% where "Oth bit" means least significant bit aka parity bit.

% Specific case

% 0 <= x < 106
% k <= y < k + 17

% Where k is a multiple of 17, k = 17 q

% Then we get binary bits of q starting from least significant one
% by chunks of 17 for each x = 0, 1, ...

% The value given for k at wikipedia page is

\xintdefiivar TupperK := 
960939379918958884971672962127852754715004339660129306651505519271702802395266
424689642842174350718121267153782770623355993237280874144307891325963941337723
487857735749823926629715517173716995165232890538221612403238855866184013235585
136048828693337902491454229288667081096184496091705183454067827731551705405381
627380967602565625016981482083418783163849115590225610003652351370343874461848
378737238198224849863465033159410054974700593138339226497249461751545728366702
369745461014655997933798537483143786841806593422227898388722980000748404719;

\xintdefiivar TupperQ, TupperR := divmod(TupperK, 17);

\xintifboolexpr{TupperR}
   {% remainder would be not zero, which is not the case with this k
    \ERROR
   }
   {% remainder is zero as expected
    \typeout{k is multiple of 17: k mod 17 = \xinttheiiexpr TupperR\relax}
   }

% Now we will assign the binary digits of q to an "array" for later use

\usepackage{xintbinhex}

\xintAssignArray
   \xintReverseDigits
      {\xintDecToBin{\xinttheiiexpr TupperQ\relax}}\to
\TupperBits

% We need 1802 = 106 * 17 bits, but turns out the two leading ones are zero
% so \TupperBits{index} only works 1<= index <= 1800

% xinttools should definitely be extended to have array-extension macro
% but it only has the very starts of "array" concept so we will need  to
% add a check in the loop using it.

\typeout{Binary rep of k/17 has only \TupperBits{0} bits, not \the\numexpr106*17.}

\begin{document}

\setlength\unitlength{1pt}

% Now we use the binary digits of q = k/17

% \TupperBits items are enumerated starting at 1 not at 0

\begin{picture}(106,17)
  \xintFor* #1 in {\xintSeq{0}{105}}\do {%
      % #1 will be x
      \xintFor* #2 in {0123456789{10}{11}{12}{13}{14}{15}{16}}\do {%
      % #2 will be y mod 17
      % Due to possibly vanishing leading bits
          \ifnum \numexpr#1*17+#2+1>\TupperBits{0}
          \else
              \if1\TupperBits{#1*17+#2+1}% charms of expandability
% The x coordinate goes from right to left and the y from top to bottom
% in Tupper plane
                 \put(\numexpr105-#1, \numexpr16-#2){\rule{1pt}{1pt}}
              \fi
          \fi
      }
  }
\end{picture}

\end{document}

使用“楼层”而不是左楼层和右楼层符号的变体

在此处输入图片描述

原始配方

1/2<floor(mod(floor(y/7)2^(-7x-mod(y,7)),2))

平面区域

0 <= x < 308, k <= y < k + 7

如下k所示。

我从公式开始,用一些在线转换器将其转换为 ascii-art。结果它产生了 8 行,其中一行是空的。所以我用 7 代替公式中的 17,然后重新开始。最后,我将位数组转换为某个数字,乘以 7 后就是这个:

k = 38426720969186584676507136423746315165273305413945565187145665641304238215561995317662843293085432836310036135900849286588951953665639729939317005809629409803737705286494507269624061838603195349517975717012314034034886568013639993815956512735232451156976667291853312484643760872115994758595671605381979339411956400072599436927196143537882844410760247627090690368478688405508823263940609428350186251562536135575229759753524677106213338248890237354234165603070460931515868266696814935467260883698401252476941050712407716221704528350212280853722118440152424270081709425589819079391652824219385549071663086397901966417260775437015400315493361455291308484

它有 650 个十进制数字,并且k/72156 = 308*7二进制数字。

原始公式位于区域0<= x < 308k <= y < k+7如上所示k。我使用的是像素化平面,其中 x 从右到左增加,y 从上到下增加, 处的单位像素的(x,y)左下角位于(x,y)

因此,该公式在评估中确实使用实数,但是x, y是整数。

遗憾的是,由于 xintexpr 使用控制序列字符串来存储标记,TeX 内存耗尽。因此,由于我花了一些时间进行设置,我恢复为直接从(计算的)二进制数字排版图片。

\documentclass{article}

\usepackage{xintexpr}

% Tupper+xintexpr

% FORMULA:

% Pixel (x, y) is ON <===> 1/2 < floor(mod(floor(y/7)2**(-7x-mod(y,7)),2))

% 0 <= x < 308
% k <= y < k + 7

\xintdefiivar TupperKvariant :=
38426720969186584676507136423746315165273305413945565187145665641304238215561995317662843293085432836310036135900849286588951953665639729939317005809629409803737705286494507269624061838603195349517975717012314034034886568013639993815956512735232451156976667291853312484643760872115994758595671605381979339411956400072599436927196143537882844410760247627090690368478688405508823263940609428350186251562536135575229759753524677106213338248890237354234165603070460931515868266696814935467260883698401252476941050712407716221704528350212280853722118440152424270081709425589819079391652824219385549071663086397901966417260775437015400315493361455291308484;

% Turns out that here k/7 has 2156 bits (= 308*7)

% conversion to binary for "cheating approach" 
\usepackage{xintbinhex}

\xintdefiivar TupperQvariant := TupperKvariant/7;
\xintAssignArray
   \xintReverseDigits
      {\xintDecToBin{\xinttheiiexpr TupperQvariant\relax}}\to
\TupperBits

% no missing "0" leading bit in that case, length is 2156=308*7

\begin{document}

\setlength\unitlength{1pt}

% \begin{picture}(308,7)
%   \xintFor* #1 in {\xintSeq{0}{307}}\do {% x
%           \xintdefiivar x = #1;% to let the formula use x, y, not #1, #2
%       \xintFor* #2 in {0123456}\do {%  y - k
%           \xintdefiivar y = #2 + TupperKvariant;%
%           \xintifboolexpr 
% % MODIFIED TUPPER FORMULA USED IN INPUT SHOWS AS IS IN OUTPUT!
%           {1/2<floor(mod(floor(y/7)2^(-7x-mod(y,7)),2))}
%              {\put(\numexpr307-#1, \numexpr6-#2){\rule{1pt}{1pt}}}
%              {}
%       }
%   }
% \end{picture}

% ARRGGGGGGGGGGGHHHHHH after about 90s

% ! TeX capacity exceeded, sorry [pool size=6162206].
% <argument> ...535738417728939435264785252352[0],2 

% so we do it by cheating

\begin{picture}(308,7)
  \xintFor* #1 in {\xintSeq{0}{307}}\do {%
      % #1 will be x
      \xintFor* #2 in {0123456}\do {%
      % #2 will be y mod 7
      % no vanishing leading bits
              \if1\TupperBits{#1*7+#2+1}% charms of expandability
% The x coordinate goes from right to left and the y from top to bottom
% in Tupper plane
                 \put(\numexpr307-#1, \numexpr6-#2){\rule{1pt}{1pt}}
              \fi
      }
  }
\end{picture}

\end{document}

相关内容