Inspired Lua 程序在计算机和计算器上不同
Inspired Lua Program is Different on Computer and Calculator
我正在尝试为我的 TI-Nspire CX CAS 创建一个简单的二次公式程序。我似乎一切都正确,并且它可以在计算机上运行:
但是,它在计算器上不起作用。我得到第二个正确的,但第一个是-4.44089 ... e-16。 (不说...,只是用它,因为我不想把整个东西都打出来)
(简化)代码如下:
function quadraticA(f,s,t)
return ((-1*s)+math.sqrt(s^2-4*f*t))/(2*f)
end
function quadraticB(f,s,t)
return ((-1*s)-math.sqrt(s^2-4*f*t))/(2*f)
end
function on.paint(gc)
formula:setExpression("0s: "..quadraticA(tonumber(a),tonumber(b),tonumber(c)))
formulaB:setExpression(quadraticB(tonumber(a),tonumber(b),tonumber(c)))
end
为什么我在计算器上得到的答案与在计算机上得到的答案不同?我该如何解决这个问题?
提前致谢!
Egor 想表达的是计算机 do not calculate exact answers 大多数时候。
Texas Instruments 主要经营微控制器,因此我不希望您的设备内装有常用的 x86-64 处理器。这意味着 TI 可以按照自己的方式做很多事情。他们可能会自行决定如何处理小值、舍入、如何处理复杂的数学运算等...
如今,计算机至少使用 32 位浮点数。 This page gives precision (number of bits before e^-16
that are correct in the machine representation). For 32 bits that value is 24
. I couldn't find much info on the calculator, except the wiki page,表示其精度为14
。超过一半的浮点数小于浮点数,该 IEEE 标准中未定义。
那边的那个sqrt
有个讨厌的函数。计算其值需要 quite a lot of computations。很多步骤意味着很多算术错误,精度越低,它得到的真实值就越远。这也取决于 sqrt
函数中选择的确切算法。您可以检查 math.sqrt(4^2)
return 是否应该 return 以及 math.sqrt(4^2))/(2*4)
return 是否正好是一半。
与计算中的数值错误作斗争本身就是一门完整的学科,具体方法因您处理的方程式而异。
有 this post 考虑二次方程。
或者在您的情况下,您可能更愿意在最终答案中只丢弃小数点后的所有数字。
正如 Dimitry 所指出的,我必须编写一个 CAS 引擎。这是 lua 中的平方根简化:
function factors(a)
factorsOfA={}
counter = 0
for i = 1, a do
counter = counter + 1
if modulo(a,i) == 0 then
factorsOfA[counter]=i
end
end
return factorsOfA
end
function simplifySqrt(radicand)
radicandFactors = factors(radicand)
outsideRadicand = 1
for m,i in pairs(radicandFactors) do
if math.floor(math.sqrt(i))^2 == i then
outsideRadicand = outsideRadicand * math.floor(math.sqrt(i))
end
end
insideRadicand = radicand/outsideRadicand^2
return outsideRadicand.."sqrt("..insideRadicand..")"
end
希望对您有所帮助!
我正在尝试为我的 TI-Nspire CX CAS 创建一个简单的二次公式程序。我似乎一切都正确,并且它可以在计算机上运行:
但是,它在计算器上不起作用。我得到第二个正确的,但第一个是-4.44089 ... e-16。 (不说...,只是用它,因为我不想把整个东西都打出来)
(简化)代码如下:
function quadraticA(f,s,t)
return ((-1*s)+math.sqrt(s^2-4*f*t))/(2*f)
end
function quadraticB(f,s,t)
return ((-1*s)-math.sqrt(s^2-4*f*t))/(2*f)
end
function on.paint(gc)
formula:setExpression("0s: "..quadraticA(tonumber(a),tonumber(b),tonumber(c)))
formulaB:setExpression(quadraticB(tonumber(a),tonumber(b),tonumber(c)))
end
为什么我在计算器上得到的答案与在计算机上得到的答案不同?我该如何解决这个问题?
提前致谢!
Egor 想表达的是计算机 do not calculate exact answers 大多数时候。
Texas Instruments 主要经营微控制器,因此我不希望您的设备内装有常用的 x86-64 处理器。这意味着 TI 可以按照自己的方式做很多事情。他们可能会自行决定如何处理小值、舍入、如何处理复杂的数学运算等...
如今,计算机至少使用 32 位浮点数。 This page gives precision (number of bits before e^-16
that are correct in the machine representation). For 32 bits that value is 24
. I couldn't find much info on the calculator, except the wiki page,表示其精度为14
。超过一半的浮点数小于浮点数,该 IEEE 标准中未定义。
那边的那个sqrt
有个讨厌的函数。计算其值需要 quite a lot of computations。很多步骤意味着很多算术错误,精度越低,它得到的真实值就越远。这也取决于 sqrt
函数中选择的确切算法。您可以检查 math.sqrt(4^2)
return 是否应该 return 以及 math.sqrt(4^2))/(2*4)
return 是否正好是一半。
与计算中的数值错误作斗争本身就是一门完整的学科,具体方法因您处理的方程式而异。 有 this post 考虑二次方程。
或者在您的情况下,您可能更愿意在最终答案中只丢弃小数点后的所有数字。
正如 Dimitry 所指出的,我必须编写一个 CAS 引擎。这是 lua 中的平方根简化:
function factors(a)
factorsOfA={}
counter = 0
for i = 1, a do
counter = counter + 1
if modulo(a,i) == 0 then
factorsOfA[counter]=i
end
end
return factorsOfA
end
function simplifySqrt(radicand)
radicandFactors = factors(radicand)
outsideRadicand = 1
for m,i in pairs(radicandFactors) do
if math.floor(math.sqrt(i))^2 == i then
outsideRadicand = outsideRadicand * math.floor(math.sqrt(i))
end
end
insideRadicand = radicand/outsideRadicand^2
return outsideRadicand.."sqrt("..insideRadicand..")"
end
希望对您有所帮助!