Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 2 из 2
  1. #1
    Аватар для Leogin
    Пользователь

    Статус
    Оффлайн
    Регистрация
    07.06.2022
    Сообщений
    13
    Репутация:
    1 ±

    Баг компилятора или павн?

    Здравствуйте, покажу пример.
    PHP код:
        new test 80*50000000
        
    printf("%d",test); // -294967296
        
        
    test 100*50000000
        
    printf("%d",test); // 705032704 
    Объясните мне такой феномен, почему так происходит, и как решать такие проблемы в будущем



    UPD:
    Но если мы попробуем так, будет все правильно отображать
    PHP код:
        new test 80*60000000;
        
    printf("%d",test); // 505032704

        
    test 100*60000000
        
    printf("%d",test); // 1705032704 

    Для Float:
    PHP код:
        new Float:test 80.0*50000000.0;
        
    printf("%f",test); // .','*).'*.000000

        
    test 100.0*50000000.0
        
    printf("%f",test); // 705032704.000000 
    Последний раз редактировалось Leogin; 31.12.2022 в 17:29.

  2. #2
    Аватар для punkochel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.12.2018
    Адрес
    Россия
    Сообщений
    146
    Репутация:
    25 ±
    Здесь ничего необычного нет. В pawn переменная имеет размер 4 байта (32 бита) знакового типа, следовательно максимально число, которое может хранить переменная это от -2 147 483 648 до 2 147 483 647.
    Целочисленное переполнение (Wikipedia)

    UPD:
    Откуда берутся такие цифры:
    Механику хранения чисел можно представить как одометр автомобиля (прибор для измерения пробега).
    1 бит может в себе хранить 0, либо 1. Это наименьшая величина измерения данных.
    1 байт - это 8 бит, значит байт можем представить как 1100 1100. В 1 беззнаковый байт мы можем записать числа от 0 до 255 (256 различных значений).
    Допустим возьмем число 255 (это наибольшее число, которое может быть записано в 1 байт), в памяти оно хранится так: 1111 1111. Если мы прибавим к этому набору битов еще 1 бит, то должно получиться так 1 0000 0000, но у нас же всего 8 бит, 9-й просто отлетает и в результате мы получим просто 0000 0000, то есть 0. Это действительно для беззнакового байта.

    Знаковые хранятся точно так-же, но самый старший бит хранит именно тот самый знак.
    Число 0 в знаковом байте хранится как: 0000 0000 (+0) или 1111 1111 (-0).
    Если мы хотим хранить число +3, то: 0000 0011.
    Если число -3: 1111 1100 (заполнение с обратной стороны).
    Получается что старший бит уже зарезервирован под хранение знака, и для хранения наших чисел остается всего 7 бит, а это от -128 до 127 (не забываем про 0), это те же 256 значений только со знаком.

    UPD 2:
    Ну и на последок. Процессор умеет только складывать числа, поэтому если сложить 0000 0011 + 1111 1100 (+3+(-3)), то произойдет тот самый перенос в несуществующий разряд и мы получим -0.
    Бывают при этом прямые и обратные виды представления отрицательных чисел. Но если интересно, то информацию найдешь в интернете.
    Последний раз редактировалось punkochel; 31.12.2022 в 19:37.

  3. Пользователь сказал cпасибо:
    Leogin (31.12.2022)
 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •