Lua十进制符号?

我在其他语言中使用过这个函数,但是 Lua 似乎缺少这个非常有用的函数。

你们中的哪位好人能为我提供一个 Lua 函数,以获取传递给它的数字的符号?

原文链接 https://stackoverflow.com/questions/1318220

点赞
stackoverflow用户108130
stackoverflow用户108130

你可以像这样检查 sign

i = -2
if i == math.abs(i) then -- 或者 i >= 0
   print "positive"
else
   print "negative"
end
2009-08-23 10:33:30
stackoverflow用户107090
stackoverflow用户107090
函数 `math.sign(x)` 返回参数 `x` 的符号。如果 `x` 小于 0,则返回 -1;如果 `x` 大于 0,则返回 1;如果 `x` 等于 0,则返回 0。

```lua
function math.sign(x)
   if x<0 then
     return -1
   elseif x>0 then
     return 1
   else
     return 0
   end
end
2009-08-23 11:30:33
stackoverflow用户312586
stackoverflow用户312586

为了以防万一有人看到这个,这是更为简短的版本:

function sign(x)
  return x>0 and 1 or x<0 and -1 or 0
end
2010-04-12 23:42:50
stackoverflow用户357410
stackoverflow用户357410

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

我会坚持使用

function sign(x)
  return (x<0 and -1) or 1
end
2010-06-03 11:34:56
stackoverflow用户1511802
stackoverflow用户1511802

你也可以像这样获取一个数的符号:

x / math.abs(x)

我只会在整数上使用它,而 Lua 并不区分整数和浮点数,所以我不会在 Lua 中使用它。

2012-07-09 11:18:35
stackoverflow用户2428487
stackoverflow用户2428487

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

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

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

只在 x86 中进行了测试。无法保证它在 LuaJIT 支持的其他处理器中最快。

2020-11-17 16:09:32
stackoverflow用户5688146
stackoverflow用户5688146

我写了这个函数是因为我需要精确地处理 -0+0nan,其他版本都无法处理。

这个函数的思路是直接解释符号位,并且使用无分支的方式进行测试。在纯 Lua 中,你需要使用 tostring(x) 来检查正负零。

    local _sign_helper = ffi.new("union { double d; uint64_t ul; int64_t l; }[1]")
    local function sign(num)
        -- 为了访问 double 类型的位表示
        _sign_helper[0].d = num

        -- 将它重新解释为 ulong,来访问符号位
        -- 1. 将位移到第一位
        -- 2. 乘以 -2 来将范围从 0/1 移到 0/-2
        -- 4. 加上 1 来将范围减小到 -1/1

        -- 处理 NaN 的另一种版本(可能更快,未经测试)
        -- return num ~= num and num or (tonumber(bit.rshift(_sign_helper[0].ul, 63)) * -2 + 1)

        -- 无分支版本:num - num 除了 NaN 外总是为 0。
        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-22 11:20:24
stackoverflow用户2755116
stackoverflow用户2755116

一种变体如下参考链接

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

根据数学上的定义,符号数学上是'+'或'-'(符号),而不是数值(如+1或-1)。

2021-07-23 18:17:50