Иконка ресурса

uint 1.0.3

Нет прав для скачивания
Поддерживаемые игры
  1. CS: Source (OrangeBox)
  2. CS: Source (v34)
  3. CS: GO
Очень простенький расшр.
Чтобы понять зачем он нужен, достаточно запустить такой плг:

C++:
public void OnPluginStart()
{
    int x = 2147483650 / 2; // Должно быть 1073741825
    PrintToServer("%%u = %u\n%%d = %d\n%u > 1000 = %s", x, x, x, x > 1000 ? "yes" : "no");
}
И увидеть:

C-подобный:
%u = 3221225473
%d = -1073741823
3221225473 > 1000 = no

Все значения неверные + сравнение не работает.
Всё ломается, когда значение превышает int лимит (2147483647).

Несколько нативов/стоков для борьбы с этими глюками:

C++:
#define UINT_SIZE 12

/**
* Math operations with unsigned int ('+', '-', '*', '/', '%')
*
* Example:
* int i = uint(2147483650, '/', 2);
* PrintToServer("%u", i); // 1073741825
*
* Note:
* unsigned int limit (4294967295) is not violated:
* 4294967295 + 1 = 4294967295
* 0 - 1 = 0
* 4294967295 * 2 = 4294967295
*/
native int uint(int a, int op, int b);

/**
* Comparison two unsigned int values
*
* Example:
* bool b = uintcmp(5, 3) >= 0; // true, if 5 >= 3 (instead of operator >=, use any. 0 must be always).
*/
native int uintcmp(int a, int b);

/**
* Replacement FormatTime, because:
*
* char s[128];
* FormatTime(s, sizeof(s), "%d.%m.%Y - %H:%M", 2147483648);
* [SM] Exception reported: Invalid time format or buffer too small (or I'm stupid and forgot to convert stamp in unsigned int)
*/
native bool FormatUTime(char[] buffer, int maxlength, const char[] format, int stamp=0);

// Convert unsigned int to string (IntToString can't) (return: Number of cells written)
stock int UIntToString(int value, char[] s, int size) {
    return FormatEx(s, size, "%u", value);
}

// Extract unsigned int from the field (SQL_FetchInt can't)
stock int SQL_FetchUInt(Handle results, int field, DBResult &result=DBVal_Error, int error=0)
{
    char s[UINT_SIZE];
    return SQL_FetchString(results, field, s, sizeof(s), result) && result == DBVal_Data ? StringToInt(s) : error;
}

Если передаёте в натив отрицательное число, то учитывайте что оно конвертнётся в unsigned int. Т.е. если нужно отнять 5 от числа, то не пишите так: uint(10, '+', -5), т.к. -5 будет преобразовано в 4294967291, а пишите uint(10, '-', 5). Если число превысило int, то оно отрицательное, т.к. в SourcePawn 2147483650 выглядит как -2147483646.

У меня сейчас нет возможности скомпилить под Linux (может найдётся кто добрый), поэтому пока только Win версия.
Автор
_wS_
Скачивания
46
Просмотры
1,318
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок

Другие ресурсы пользователя _wS_

Последние обновления

  1. FormatUTime быстрее на 46.72%

    Циклов для 4294967295 было: 73005, стало: 49759. Было бы круче добавлять сначала годы/месяцы...
  2. Исправлена функция FormatUTime и добавлена версия для Linux

    В 1.0.1 FormatUTime работало неверно на Linux. Изменил принцип работы. Тесты показали что всё ок.
  3. Зачем нам краш из-за FormatTime и его int ограничения

    native bool FormatUTime(char[] buffer, int maxlength, const char[] format, int stamp=0); public...
Сверху