Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Mathematical functions - Gideros Forum

Mathematical functions

Is there a better function to get a number sign?
a=-456
anti_abs=math.abs(a)/a 
print(anti_abs)
--> -1
 
a=456
anti_abs=math.abs(a)/a 
print(anti_abs)
--> 1
my games:
https://play.google.com/store/apps/developer?id=razorback456
мій блог по гідерос https://simartinfo.blogspot.com
Слава Україні!

Comments

  • MoKaLuxMoKaLux Member
    edited November 9
    I found this SO question, in case you haven't seen it. Hope this helps?

    https://stackoverflow.com/questions/441893/which-is-faster-math-absvalue-or-value-1
  • olegoleg Member
    edited November 9
    MoKaLux said:

    I found this SO question, in case you haven't seen it. Hope this helps?

    https://stackoverflow.com/questions/441893/which-is-faster-math-absvalue-or-value-1

    I asked about the opposite function, look more closely
     anti_abs=math.abs(a)/a
    or
    function anti_abs(a) if a<0 then return -1 else return 1 end  end

    Likes: MoKaLux

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 ) Share on Facebook
  • oops, that didn't help :)

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • hgy29hgy29 Maintainer
    Accepted Answer
    A good question for the profiler :) maybe ((a*a)^0.5)/a

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    keszegh said:

    comparing with 0 is slow?

    Not concise
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • SinisterSoftSinisterSoft Maintainer
    Accepted Answer
    Here is my version... :)
    a=-456
    anti_abs=(a<>-1)><1
    print(anti_abs)
     
    a=456
    anti_abs=(a<>-1)><1
    print(anti_abs)
     
    a=0
    anti_abs=(a<>-1)><1
    print(anti_abs)</pre>

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    edited November 10

    Here is my version... :)

     
    a=0
    anti_abs=(a<>-1)><1
    print(anti_abs)</pre>
    Zero should give +1, not 0

    All the examples are wrong with zero ...

    Exept this..
    if a<0 then return -1 else return 1 end :(
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • rrraptorrrraptor Member
    edited November 10 Accepted Answer
    max@1000000
    calls @ 10
    a @ -458
     
     
    local abs=math.abs
    function test1()
    	for loop=1,max do
    		local sign=math.abs(a)/a
    	end
    end
     
    function test2()
    	for loop=1,max do
    		local sign=1
    		if a<0 then sign=-1 end
    	end
    end
     
    function test3()
    	for loop=1,max do
    		local sign=a < 0 and -1 or 1
    	end
    end
     
    function test4()
    	for loop=1,max do
    		local sign=abs(a)/a
    	end
    end
     
    function test5()
    	for loop=1,max do
    		local sign= ~((-a >> 31) - (a >> 31))+1
    	end
    end
     
    function test6()
    	for loop=1,max do
    		local sign = (((a >> 31 ) + 1) << 1)-1
    	end
    end
     
    Core.profilerReset()
    Core.profilerStart()
    for loop=1,calls do
    	test1()
    	test2()
    	test3()
    	test4()
    	test5()
    	test6()
    end
    Core.profilerStop()
     
    -- print the results of the profiler
    result=Core.profilerReport()
    print("Number of tests:",max*calls)
    for k,v in pairs(result) do
    	local found=false
    	for k2,v2 in pairs(v) do
    		if found and k2=="time" then print(v1,v2) end
    		if k2=="name" and string.sub(v2,1,4)=="test" then v1=v2 found=true end
    	end
    end


    Core i7-8700:
    Number of tests: 10000000
    test1 2.0068597
    test2 0.11249119999957
    test3 0.12390259999756
    test4 2.1758287000011
    test5 0.17857100000037
    test6 0.14978380000048
    Android Snapdragon 660:
    Number of tests: 10000000
    test1 11.119264109991
    test2 0.3629721889738
    test3 0.38107234399649
    test4 11.203031454002
    test5 0.66782401097589
    test6 0.58520260301884
    ((a*a)^0.5)/a
    fastest, but gives incorrect result with 0
    I guess, #2 or #3 is ok. Less than a sec., shoud be good :wink:

    EDIT:
    Found one more way:
    local sign = ~((-a >> 31) - (a >> 31))+1
    It returns -1/0/1 but slower than just
    a < 0 and -1 or a > 0 and 1 or 0
    EDIT2
    Hmm, I wonder why bit operations slower that just "x < y and a or b"?
    This give us -1 for neagative and 1 for 0 and positive numbers
    (((a >> 31 ) + 1) << 1)-1
    But again, slower than
    a < 0 and -1 or 1

    Likes: MoKaLux, hgy29, oleg

    +1 -1 (+3 / -0 ) Share on Facebook
  • wikipedia:
    Zero itself is without a sign, or signless.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • olegoleg Member
    keszegh said:

    wikipedia:
    Zero itself is without a sign, or signless.

    In our case "-1" and "+1" is not a number - it's a "sign" of the number. 456 * -1 =-456

    All other values ​​except "-1" and "+1" will cause errors in the program
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • value 0 would be more natural as the sign of 0, and multiplying with 0 won't throw an error.
  • olegoleg Member
    keszegh said:

    wikipedia:
    Zero itself is without a sign, or signless.

    Zero sign doesn't matter '+' or '-', but it must be '+1' or '-1'
    For my program only 3 ways will not cause an error in the program:

    1.@rrraptor
    a<0 and -1 or a > 0 and 1 or 0

    2.@SinisterSoft
    a=0
    anti_abs=(a<>-1)><1
    print(anti_abs)

    3.if a<0 then return -1 else return 1 end

    And my example and example @hgy29 will give a value of 'nan' and cause an error
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • olegoleg Member
    keszegh said:

    value 0 would be more natural as the sign of 0, and multiplying with 0 won't throw an error.

    If I want to move the sign '-' numbers '-0' to another number '456' multiplication by 0 will return 0 and must return 456.

    So there are only '-1' and '+1' and '0' is not allowed
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • SinisterSoftSinisterSoft Maintainer
    edited November 10
    Technically 0 has no sign. So there are two solutions test7 and test8 ... (pretty old xeon)

    test7 results with:
    -1 if neg, 0 if 0, +1 if pos

    test8 result with:
    -1 if neg, 0 if not neg

    function test7()
    for loop=1,max do
    local sign =(a<>-1)><1
    end
    end

    function test8()
    for loop=1,max do
    local sign =(a<>-1)><0
    end
    end

    test1 4.5261051000002
    test2 0.23030710000012
    test3 0.25647970000023
    test4 4.9691175000003
    test5 0.48598210000046
    test6 0.3186288000004
    test7 0.17589819999989
    test8 0.17575890000012

    :)

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook

  • I also added a test9 in case being -1 or +1 was important, test9 will give -1 if neg and +1 if pos (inc zero)...

    function test9()
    for loop=1,max do
    local sign =((a<>-1)><0)|1
    end
    end

    test2 0.23013360000004
    test3 0.25745690000076
    test5 0.37778469999967
    test6 0.31808180000007
    test7 0.17587430000003
    test8 0.17580960000032
    test9 0.24851379999927

    I removed the two crazy slow functions (1 and 4)!

    I think the bitwise operators deal with real numbers so they have to do conversions, so they slow down. If they were true bitwise operators then I think 9 would be faster than 2.

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    Accepted Answer
    Just noticed because of the order you don't need the brackets so:

    test7
    sign=a<>-1><1

    test8
    sign=a<>-1><0

    test9
    sign=a<>-1><0|1

    timings are the same though, just saves typing!

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • Technically 0 has no sign but in some old projects I ended up with -0 sometimes which caused a lot of issues.
  • olegoleg Member
    edited November 11
    antix said:

    Technically 0 has no sign but in some old projects I ended up with -0 sometimes which caused a lot of issues.

    Technically, the absence of a sign is a '+' sign

    -3,, -2, -1, 0, 1 ,2 B)

    Likes: antix

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 ) Share on Facebook
  • If zero has no negative value then it's not negative. If zero has no positive value then it's not positive. So zero has no sign. :)
  • olegoleg Member

    If zero has no negative value then it's not negative. If zero has no positive value then it's not positive. So zero has no sign. :)

    Move the sign (or no sign) from zero to another number. ;)


    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • @oleg, technically that is correct but if Lua/Gideros/Whatever returns a -0 you get all kinds of strange behavior :D
  • olegoleg Member
    antix said:

    @oleg, technically that is correct but if Lua/Gideros/Whatever returns a -0 you get all kinds of strange behavior :D

    Logically, at '-0' the character should return '-1'

    Assuming '-0' is an infinite negative number '-0,000000000000001'


    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • It doesn't return what you might logically expect. Usually its not hard to remember and you can make corner case code to accommodate for it... it is just annoying :)
  • olegoleg Member
    antix said:

    It doesn't return what you might logically expect. Usually its not hard to remember and you can make corner case code to accommodate for it... it is just annoying :)

    You can do the right function that will return 0 correctly.

    For example, there is a math.atan2 function which correctly returns zero

    Instead of the math.atan function
    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
  • Interesting. I've got -0 results doing normal math and think that it is pretty dumb to have to then pass results through another math function just in case they are incorrect? Oh well, it's all fun and games ;)
  • olegoleg Member
    edited November 14
    antix said:

    Interesting. I've got -0 results doing normal math and think that it is pretty dumb to have to then pass results through another math function just in case they are incorrect? Oh well, it's all fun and games ;)

    My familiar math professor to work around problems with 0, just uses 0.0001 instead of zero. No exact precision is required in mathematics, no one uses the number pi with all signs. - logical to do so that would simplify the calculations with a tolerance in the calculations


    ps/ The sign -0 cannot be because:

    -0 = x*-0%
    -1 = x*-100%
    The sign number is always the digit '1'

    33*-1=-33
    33*-0 =0 error!!

    Likes: antix

    my games:
    https://play.google.com/store/apps/developer?id=razorback456
    мій блог по гідерос https://simartinfo.blogspot.com
    Слава Україні!
    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.