1

I am trying to return very long integer number but my result returns as "7.6561197971049e+016". How do I make it return 76561197971049296 ?

local id64 = 76561197960265728
Z = string.match("STEAM_0:0:5391784", 'STEAM_%d+:%d+:(%d+)')
Y = string.match("STEAM_0:0:5391784", 'STEAM_%d+:(%d+):%d+')
--For 64-bit systems
--Let X, Y and Z constants be defined by the SteamID: STEAM_X:Y:Z.
--Let V be SteamID64 identifier of the account type (0x0110000100000000 in hexadecimal format).
--Using the formula W=Z*2+V+Y
if Z == nil then
    return "none"
else
    return Z*2+id64+Y
end

I installed lbc arbitrary precision now with this code

return  bc.add(bc.number(id64),bc.number(2)):tostring()

it returns 70000000000000002 but if I delete 3 digits from id64 it displays correctly.

How can I get correct result without deleting the digits?

Fiat Pax
  • 417
  • 6
  • 18
  • Thank you so much @lhf for the tip to extract with a single match and also for showing how to pass as a string to bc. That worked! – Fiat Pax Aug 08 '13 at 21:22
  • 2
    If your long ints fit in 64 bits, try my lint64, available at http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lint64, which is smaller and simpler than lbc. – lhf Aug 09 '13 at 01:22
  • Yes they do, I am using your lint64 library now, thanks again. – Fiat Pax Aug 09 '13 at 03:51

4 Answers4

3

You need to use strings for long numbers. Otherwise, the Lua lexer converts them to doubles and loses precision in this case. Here is code using my lbc:

local bc=require"bc"
local id64=bc.number"76561197960265728"
local Y,Z=string.match("STEAM_0:0:5391784",'STEAM_%d+:(%d+):(%d+)')
if Z == nil then
    return "none"
else
    return (Z*2+id64+Y):tostring()
end
lhf
  • 70,581
  • 9
  • 108
  • 149
2

Assuming your implementation of Lua supports that many significant digits in the number type, your return statement is returning that result.

You're probably seeing exponential notation when you convert the number to a string or printing it. You can use the string.format function to control the conversion:

assert( "76561197971049296" == string.format("%0.17g", 76561197971049296))

If number is an IEEE-754 double, then it doesn't work. You do have to know how your Lua is implemented and keep in mind the the technical limitations.

Tom Blodget
  • 20,260
  • 3
  • 39
  • 72
  • Thank you, it doesn't support, I had to install lbc arbitrary precision library and now I have that problem I commented to collapsar. – Fiat Pax Aug 08 '13 at 20:41
  • 3
    Too bad 76561197971049296 needs 57 bits and doubles only give you 53. – lhf Aug 08 '13 at 21:17
  • Argh, the test in my answer works at [Lua Demo](http://www.lua.org/cgi-bin/demo). But, I should have tried `assert( 76561197971049296 == 76561197971049296 - 1)`, which doesn't. – Tom Blodget Aug 08 '13 at 21:25
1

check out this library for arbitrary precision arithmetics. this so post might be of interest to you as well.

Community
  • 1
  • 1
collapsar
  • 17,010
  • 4
  • 35
  • 61
  • Thank you for pointing me to the library, there is something i don't understand now with this code: bc.add(id64,2):tostring() it returns 70000000000000002 why so? id64 is 76561197960265728. – Fiat Pax Aug 08 '13 at 20:27
  • use `bc.add(id64,bc.number(2)):tostring()`. – collapsar Aug 08 '13 at 20:46
  • It still returns 70000000000000002, I also tried this. bc.add(bc.number(id64),bc.number(2)):tostring() – Fiat Pax Aug 08 '13 at 20:50
1

If you have luajit installed, you can do this:

local ffi = require("ffi")

steamid64 = tostring(ffi.new("uint64_t", 76561197960265728) + ffi.new("uint64_t", tonumber(accountid)))
steamid64 = string.sub(steamid64, 1, -4) -- to remove 'ULL at the end'

Hope it helps.

jvperrin
  • 3,368
  • 1
  • 23
  • 33