8

我在其他语言中使用过这个,但是 lua 似乎缺少这个相当有用的功能。

你们中的一个好家伙可以给我一个lua函数来获取传递给它的数字的符号吗?

4

8 回答 8

16
function math.sign(x)
   if x<0 then
     return -1
   elseif x>0 then
     return 1
   else
     return 0
   end
end
于 2009-08-23T11:30:33.487 回答
11

以防万一有人偶然发现这个:,这是我的较短版本:

function sign(x)
  return x>0 and 1 or x<0 and -1 or 0
end
于 2010-04-12T23:42:50.663 回答
4

我认为这个想法是返回 1 或 -1 来表示正面或负面。我认为您不希望它返回 0。可能会产生灾难性的影响。想象一下,当一个值返回 0 时,试图通过将它乘以 sign(x) 来改变它的符号。而不是改变符号,你会将值更改为 0。

我会坚持

function sign(x)
  return (x<0 and -1) or 1
end
于 2010-06-03T11:34:56.937 回答
0

使用 LuaJIT,如果 sign 函数被 JIT 编译,这实际上更快:

function sign(x)
  return math.max(math.min(x * 1e200 * 1e200, 1), -1)
end

原因是它避免了分支,这可能很昂贵。双倍乘法确保即使输入在非正规范围内,结果也是正确的。Infinity 不能使用,因为输入为零,它会产生 NaN。

仅在 x86 中测试。我不能保证它是 LuaJIT 支持的其他处理器中最快的。

于 2020-11-17T16:09:32.370 回答
0

我建造了这个是因为我需要精确处理-0以及所有其他版本都无法处理的问题。+0nan

这个想法是直接解释符号位并为此测试提供无分支版本。在纯 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  


于 2021-04-22T11:20:24.713 回答
-1

您还可以像这样获得数字的符号:

x/ math.abs(x)

我只会将那个用于整数,并且由于 Lua 不区分整数和浮点数,所以我根本不会在 Lua 中使用它。

于 2012-07-09T11:18:35.403 回答
-1

一种变化可能

function sign(x)
   if x<0 then
     return "-"
   elseif x>0 then
     return "+"
   else
     return ""
   end
end

在数学上,符号是“+”或“-”(符号),而不是数字(如 +1 或 -1)

于 2021-07-23T18:17:50.503 回答
-3

你可以检查sign这样的:

i = -2
if i == math.abs(i) then -- or i >= 0
   print "positive"
else
   print "negative"
end
于 2009-08-23T10:33:30.637 回答