Lua小数点符号?

发布于 2024-08-02 10:27:00 字数 86 浏览 2 评论 0原文

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

你们中的一位好心人能给我提供一个 lua 函数来获取传递给它的数字的符号吗?

I've used this in other languages, but lua seems to be lacking this rather useful function.

Could one of you nice chappies provide me a lua function to get the sign of the number passed to it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

つ低調成傷 2024-08-09 10:27:00
function math.sign(x)
   if x<0 then
     return -1
   elseif x>0 then
     return 1
   else
     return 0
   end
end
function math.sign(x)
   if x<0 then
     return -1
   elseif x>0 then
     return 1
   else
     return 0
   end
end
鱼忆七猫命九 2024-08-09 10:27:00

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

function sign(x)
  return x>0 and 1 or x<0 and -1 or 0
end

Just in case anyone stumbles on this one:, here's my somehow shorter version:

function sign(x)
  return x>0 and 1 or x<0 and -1 or 0
end
不可一世的女人 2024-08-09 10:27:00

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

我会坚持使用

function sign(x)
  return (x<0 and -1) or 1
end

I think the idea is to return 1 or -1 to represent positive or negative. I don't think you would want it to return 0. Could have disastrous effects. Imagine trying to change the sign of a value by multiplying it by sign(x) when it returns 0. Instead of changing the sign you'd change the value to 0.

I'd stick with

function sign(x)
  return (x<0 and -1) or 1
end
中二柚 2024-08-09 10:27:00

使用 LuaJIT,如果符号函数得到 JIT 编译,这实际上会更快:

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

原因是它避免了分支,而分支的成本可能很高。即使输入在非正规范围内,双重乘法也可确保结果正确。不能使用无穷大,因为输入为零时会产生 NaN。

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

With LuaJIT, if the sign function gets JIT-compiled, this is actually faster:

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

The reason is that it avoids branches, which can be expensive. The double multiplication ensures that the result is correct even with inputs in the denormal range. Infinity can't be used because with an input of zero, it would produce NaN.

Tested in x86 only. I can't guarantee that it's the fastest in other processors supported by LuaJIT.

人海汹涌 2024-08-09 10:27:00

我构建这个版本是因为我需要精确处理 -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  


I built this one because I needed exact handling for -0 and +0 as well as for nan which all the other versions do not handle.

The idea is to interpret the sign bit directly and have a branchless version for this test. In pure Lua you'd have to go with tostring(x) checks +-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  


深海夜未眠 2024-08-09 10:27:00

你还可以像这样得到一个数字的符号:

x/ math.abs(x)

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

You can also get the sign of a number like this:

x/ math.abs(x)

I'd only use that one for integers and since Lua doesn't distinguish ints from floats, I'd not use it in Lua at all.

蓝海 2024-08-09 10:27:00

的变体在

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

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

A variation of that could be

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

Mathematically, the sign is '+' or '-' (a symbol), not a number (as +1 or -1)

遗忘曾经 2024-08-09 10:27:00

您可以像这样检查sign

i = -2
if i == math.abs(i) then -- or i >= 0
   print "positive"
else
   print "negative"
end

You can check for the sign like this:

i = -2
if i == math.abs(i) then -- or i >= 0
   print "positive"
else
   print "negative"
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文