本地计算机、lua 编译器和 overleaf 上 LuaLaTeX 计算结果不同

本地计算机、lua 编译器和 overleaf 上 LuaLaTeX 计算结果不同

以下是代码。它利用了以下链接中的 matrix.lua 文件。 https://github.com/davidm/lua-matrix/blob/master/lua/matrix.lua

matrix.lua下面的代码要被文件在同一个目录下运行tex,并且要用LuaLaTeX引擎进行编译。

\documentclass{article}
\begin{document}
\def\n{{{2,4,6},{8,10,12},{14,16,20}}}
\directlua{local matrix = require "matrix"
tex.sprint(matrix.latex(matrix.pow(\n,50)))}
\end{document}

当我运行该命令时 tex.sprint(matrix.latex(matrix.pow(\n,-50)))。没有问题。它运行良好并以科学计数法给出答案。因此,幂 -50 没有问题。但是幂 50 给出的答案完全错误。这绝对不是 lua 或 matrix.lua 的问题。这是因为当我在本地计算机上的 lua 中运行以下命令时,我得到了正确的答案。

local matrix = require "matrix"
n={{2,4,6},{8,10,12},{14,16,20}}
print(matrix.latex(matrix.pow(n,50)))

我在 overleaf 上运行代码时也得到了正确的答案。基本上,我本地计算机上的 lua 编译器和 overleaf 编译器的答案是一致的。但我电脑上的 LuaLaTeX 编译器生成的答案与我电脑上的 lua 编译器或 overleaf 上的答案不同。那么问题出在哪里?

  1. 本地计算机有问题吗?如果是,我如何用 -50 次方得到正确答案。我在计算机上的 lua 编译器中也得到了正确答案。

  2. 为什么 overleaf 编译器和我的本地计算机上的答案对于 50 次方不同。它们对于 -50 次方匹配。

  3. 这个问题是否与本地计算机的容量有关,例如处理器、操作系统、32 位或 64 位、内存等?

注意:文件matrix.lua中的matrix.latex函数存在一些问题。它在矩阵的每一行开头和最后一行的最后一项中打印了一些不必要的字符。我已经修复了它。但对于这个问题,它可以忽略不计。

答案1

您遇到了 Lua 5.3 的新整数数据类型,它是 TeX Live 2019 中 LuaTeX 1.10.1 的一部分。当 Lua 遇到可以用 64 位整数表示的数字时,Lua 将不再将其转换为浮点数并失去精度,而是将其以全精度存储在合适的整数类型中。但是,使用整数不仅能获得它们的优点,还能获得它们的缺点,其中之一是溢出

对于浮点数,如果数字变得太大而无法表示,它就会变成负数inf,但是整数由于其在内存中的布局而不会这样表现。如果整数变得太大,它将回绕并变为负数。你可以自己尝试一下:

$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> print(9223372036854775807 + 1)
-9223372036854775808

这正是您在代码中看到的。

但有办法解决这个问题。如果你不想使用整数,也可以不这样做。只需在.0文字后面附加一个,告诉 Lua 你想使用浮点数即可。

$ lua5.3
Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
> print(9223372036854775807.0 + 1.0)
9.2233720368548e+18

答案2

texlive 2019 luatex 中使用的 Lua 5.3 具有 (64 位) 整数类型。

您需要决定想要的结果,以及是否使用整数或浮点 64 位类型。

文件

a=1024*1024*1024*1024*1024*1024*1024 -- 2^70
print(a)

试图获取整数 2^70

使用 luatex 1.10 及更高版本生成 0:

$ texlua in1.lua
0

但较旧的 luatex 产生了近似结果:

$ /usr/local/texlive/2018/bin/x86_64-cygwin/texlua in1.lua
1.1805916207174e+21

因此,您可能会想通过强制执行双重操作来解决这个问题,例如这个版本1.0

a=1.0*1024*1024*1024*1024*1024*1024*1024 -- 2^70
print(a)

在两个系统上均产生 1.1805916207174e+21。

但请注意,double 需要一些位来存储指数,因此虽然它不会在 2^64 时溢出,但它无法准确存储 2^56 以上的整数

比较此计算 2^60 然后加 1 的文件。

a=1024*1024*1024*1024*1024*1024
print(a)
b=a+1
print(b)
print (a == b)

这适用于 Lua 5.3 的精确整数运算

$ texlua in.lua
1152921504606846976
1152921504606846977
false

但在 Lua 5.2 中可以进行双精度运算,并且最终结果为真而不是假。

$ /usr/local/texlive/2018/bin/x86_64-cygwin/texlua in.lua
1.1529215046068e+18
1.1529215046068e+18
true

相关内容