Программа Inspired Lua отличается на компьютере и калькуляторе

Я пытаюсь создать простую программу квадратичных формул для моего 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

Почему на калькуляторе я получаю другой ответ, чем на компьютере? Как я могу решить проблему?

Заранее спасибо!


person CtrlAltF2    schedule 12.05.2018    source источник
comment
-4+math.sqrt(4^2) не равно точно 0   -  person Egor Skriptunoff    schedule 13.05.2018
comment
При работе с числами с плавающей запятой вам нужно научиться не полагаться на точные значения. «что-то E-16» достаточно нуля для большинства целей.   -  person Cubic    schedule 13.05.2018


Ответы (2)


Егор пытается сказать, что компьютеры большую часть времени не вычисляют точные ответы . .

Texas Instruments занимается в основном микроконтроллерами, поэтому я не ожидаю, что в вашем устройстве будет обычный процессор x86-64. Это означает, что TI может многое сделать по-своему. Они могут принимать собственные решения о том, как обрабатывать небольшие значения, округлять, как обрабатывать сложные математические операции и т. д.

В наши дни компьютеры используют как минимум 32-битные числа с плавающей запятой. Эта страница дает точность (количество битов до e^-16, которые являются правильными в машинном представлении). Для 32 бит это значение равно 24. Я не смог найти много информации о калькуляторе, кроме вики-страницы, где говорится его точность равна 14. Более чем наполовину с плавающей запятой меньше, чем с плавающей запятой, не определено в этом стандарте IEEE.

У этого sqrt неприятная функция. Вычисление его значения требует довольно большого количества вычислений. Много шагов означает много арифметических ошибок, чем ниже точность, тем дальше от истинного значения. Это также зависит от точного алгоритма, выбранного в функции sqrt. Вы можете проверить, возвращает ли math.sqrt(4^2) то, что должно возвращать, и возвращает ли math.sqrt(4^2))/(2*4) ровно половину этого.

Борьба с числовыми ошибками в вычислениях — это отдельная дисциплина, и рецепты различаются в зависимости от того, какое уравнение вы решаете. В этот пост рассматриваются квадратные уравнения.

Или, может быть, в вашем случае вам будет удобнее просто отбросить все числа, кроме нескольких, после запятой в окончательном ответе.

person Dimitry    schedule 13.05.2018
comment
В настоящее время они используют ARM9 ( графический калькулятор ) - person soegaard; 14.05.2018

Как указал Дмитрий, я должен написать, по сути, движок 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

Надеюсь, это поможет!

person CtrlAltF2    schedule 13.05.2018
comment
Это может быть sqrt(4) = 1.999999999, поэтому floor(sqrt(4))^2 == 1 - person Egor Skriptunoff; 13.05.2018
comment
Егор Скриптунов Я с таким не сталкивался. Есть ли функция раунда в Lua? - person CtrlAltF2; 13.05.2018
comment
Не по умолчанию минимализм доведен до фанатизма в дизайне языка. Его можно реализовать вручную lua-users.org/wiki/SimpleRound . Тем не менее, ваш калькулятор может иметь что-то встроенное, вы должны проверить руководство. - person Dimitry; 14.05.2018