Sou totalmente novo em Lua e não consigo entender isso: a função a seguir sempre retorna 99, mesmo que o angleNumber seja 2,3,4 etc.
Estou negligenciando alguma peculiaridade da sintaxe Lua?
local function mirroredNumber (angleNumber)
if angleNumber == 2 then
return 8
elseif angleNumber == 3 then
return 7
elseif angleNumber == 4 then
return 6
elseif angleNumber == 6 then
return 4
elseif angleNumber == 7 then
return 3
elseif angleNumber == 8 then
return 2
else
return 99
end
end
Tentei definir uma variável local na instrução if e retorná-la no final, o que também não funcionou, então presumo que minhas verificações if/elseif estão erradas, mas não consigo descobrir como.
Existem duas peculiaridades relevantes de Lua, uma das quais eu suspeito que esteja em jogo aqui:
Vamos primeiro simplificar seu exemplo:
Assim
f(1)
é0
, ef(x)
é1
para tudox
que não é igual1
.Cordas que grasnam como números
Lua tem um "recurso" controverso onde força strings a números se você fizer aritmética com elas, e coage números a strings se você fizer aritmética com elas;
print
apenas chamatostring
internamente, o que não cita strings, então strings "quack como números". No entanto, o teste de igualdade (ou indexação de tabela) é "estrito"; também requer que os tipos correspondam. Veja este exemplo:A solução aqui, assumindo
x
que é uma string que vem de um arquivo ou similar, é totonumber(x)
(ou equivalente:x + 0
, que se comporta aproximadamente comoassert(tonumber(x))
).Erros de arredondamento
Lua usa carros alegóricos para representar números. Os flutuadores podem representar números inteiros de até 2 ^ 53 com precisão (sem perda de precisão), portanto, muitas vezes isso não é um problema ao trabalhar com números inteiros. No entanto, você pode construir carros alegóricos que sejam muito próximos de números inteiros, mas que não sejam números inteiros nos bastidores. Infelizmente Lua arredonda os números ao imprimi-los, então você não verá isso se inserir impressões de depuração. Considerar:
Para descobrir isso, imprima
x
com 17 dígitos de precisão:Se você sabe que está trabalhando com imprecisões, você deve fazer comparações com alguma “espaço para erro”. Então, em vez de testando
x == 1
, você testariamath.abs(x - 1) < 1e-6
onde1e-6
estaria sua margem (absoluta) de erro neste exemplo. (Nota: Uma margem relativa de erro pode ser mais apropriada às vezes; flutuações em particular garantem certos erros relativos).Nota lateral: em muitas linguagens com
switch
es, correspondência de padrões ou similar, uma função e umswitch
+return
podem ser uma forma idiomática de implementar isso. No entanto, dado que este é apenas um mapeamento de alguns números para outros números, você normalmente usaria uma tabela em Lua:(além disso, parece haver uma correspondência simples entre números "espelhados" e
x
(if angleNumber >= 2 and angleNumber <= 8 then return 10 - angleNumber end
), a menos que você tenha simplificado para este exemplo; por que não aproveitar isso?)