私はこれを他の言語で使用しましたが、lua にはこの便利な機能が欠けているようです。
素敵なチャッピーの 1 人が、渡された数値の符号を取得する lua 関数を提供してくれませんか?
function math.sign(x)
if x<0 then
return -1
elseif x>0 then
return 1
else
return 0
end
end
誰かがこれに出くわした場合に備えて:, これが私のどういうわけか短いバージョンです:
function sign(x)
return x>0 and 1 or x<0 and -1 or 0
end
アイデアは、正または負を表すために 1 または -1 を返すことだと思います。0 を返したくないと思います。悲惨な結果になる可能性があります。値が 0 を返すときに、sign(x) を掛けて値の符号を変更しようとしていると想像してください。符号を変更する代わりに、値を 0 に変更します。
私は固執します
function sign(x)
return (x<0 and -1) or 1
end
-0
これを構築したのは、 とを正確に処理する必要があり、他のすべてのバージョンが処理しないもの+0
も同様です。nan
アイデアは、符号ビットを直接解釈し、このテスト用に分岐のないバージョンを用意することです。純粋な Lua では、tostring(x) チェック +-0 を使用する必要があります。
local _sign_helper = ffi.new("union { double d; uint64_t ul; int64_t l; }[1]")
local function sign(num)
-- to get access to the bit representation of double
_sign_helper[0].d = num
-- reinterpret it as ulong to access the sign bit
-- 1. move the bit down to the first bit
-- 2. multiply by -2 to move the range from 0/1 to 0/-2
-- 4. add 1 to reduce the range to -1/1
-- one test version for NaN handling (might be faster, did not test.)
-- return num ~= num and num or (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1)
-- branchless version: num - num will always be 0 except for nan.
return (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1) * ((num - num + 1) / 1)
end
print("(number < 0)", sign(-3)) -- > -1
print("(number > 0)", sign(3)) -- > 1
print("(nan)", sign(0 / 0)) -- > nan
print("(-inf)", sign(-0 / 1)) -- > -1
print("(+inf)", sign(0 / 1)) -- > 1
print("(+0)", sign(0)) -- > 1
print("(-0)", sign(-0)) -- > -1
次のように数値の符号を取得することもできます。
x/ math.abs(x)
私はこれを整数にのみ使用します。Lua は int と float を区別しないため、Lua ではまったく使用しません。
そのバリエーションは
function sign(x)
if x<0 then
return "-"
elseif x>0 then
return "+"
else
return ""
end
end
数学的には、記号は「+」または「-」(記号) であり、数値 (+1 または -1) ではありません。
sign
次のように確認できます。
i = -2
if i == math.abs(i) then -- or i >= 0
print "positive"
else
print "negative"
end