Calculation not working?
#1

I have a function that calculates the days hours and minutes left in a persons ban. I noticed once the time variable got above 10 integers, the function literally makes up its own number and doesnt work. Ive debugged the mess out of it and still cant get it working.

Can someone help me fix it?

pawn Код:
stock CalculateBanTime(time)
{
    new
        iTime = gettime(),
        String[50],
        String2[200];
    if(time > iTime)
    {
        new nTime = time - iTime;
        new number[3];
        for(new i; i< 40; i++)
        {
            if(nTime >= 86400)
            {
                nTime = nTime - 864000;
                number[0]++;
            }
        }
        for(new i; i< 40; i++)
        {
            if(nTime >= 3600)
            {
                nTime = nTime - 3600;
                number[1]++;
            }
        }
        for(new i; i< 30; i++)
        {
            if(nTime >= 60)
            {
                nTime = nTime - 60;
                number[2]++;
            }
        }
        if(number[0] >= 1)
        {
            format(String,sizeof(String),"%i Days ",number[0]);
            strcat(String2,String,sizeof(String2));
            print(String);
        }
        if(number[1] >= 1)
        {
            format(String,sizeof(String),"%i Hours ",number[0]);
            strcat(String2,String,sizeof(String2));
            print(String);
        }
        if(number[2] >= 1)
        {
            format(String,sizeof(String),"%i Minutes",number[0]);
            strcat(String2,String,sizeof(String2));
            print(String);
        }
    }
    else
    {
        format(String,sizeof(String),"Not Banned");
        strcat(String2,String,sizeof(String2));
    }
    return String2;
}
Reply
#2

Do you mean when the "time" parameter you pass in is greater than 10 digits? If this algorithm works fine for numbers under 10 digits then I would guess it's because of how the underlying bits are represented for Pawn variables. A 32-bit signed integer has a range of -2,147,483,648 to 2,147,483,647 (~10 digits). Any single variable in SA:MP's Pawn is a 32-bit signed integer.

When a variable goes over the 32-bit signed integer maximum it will wrap around to the lowest negative integer that can be represented in 32-bits. It is not something you can fix in your script, only something you can work around. Possible workarounds include using a "BigInteger" array instead of a single variable (it's not part of SA:MP, you'll have to build it yourself or hope someone else has), limit the accuracy of your timespan (e.g. have 1 unit mean an hour instead of minutes or seconds), or simply don't allow numbers past the maximum to be passed to the method.

See the documentation for cellmax in the Pawn Language Guide (pawn-lang.pdf) for proof of usual the largest number in Pawn. You can also see cellbits to know how many bits are in a cell.
Reply
#3

That makes sense. Will the gettime() function even exceed that number though? Or am i just worried for no reason?
Reply
#4

Yes, but it is out of your control script-wise. The SA-MP server/Pawn virtual machine will need to update to 64-bits before then. Eventually it will hit the year 2038 problem (similar to Y2K) unless SA:MP updates to 64-bit.
Reply
#5

So im good for a "few" years haha. Thanks.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)