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

    Статус
    Оффлайн
    Регистрация
    08.08.2018
    Сообщений
    59
    Репутация:
    2 ±

    Превратить "1000000" в "1 000 000"

    Hello, World! Как максимально эффективно вытащить из числа (желательно именно числа, так как числа будут большие, порядком до 10 миллиардов, что превышает ограничение valstr() ) строку с разделением каждого третьего знака для облегчения визуализации? Мне нужен метод с 1 параметром числового типа (если можно так выразиться, учитывая что pawn бестиповый), который будет возвращать строковое представление числа с разделителями в виде пробела, или запятой. Пробовал математически, циклически и даже с побайтовым переносом символов из ячейки в ячейку с постановкой запятых каждые три ячейки с конца, но всё не то. Уповаю на вашу помощь. Вот пример того, как хотелось бы видеть команду:
    1. print(intcommas(123456789000)); // в консоли: "123 456 789 000"


    Важна работоспособность с большими числами
    Последний раз редактировалось Josan_Solomon; 08.09.2018 в 05:49.

  2. #2
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    http://forum.sa-mp.com/showthread.php?t=184328
    Там все ссылки не работают, возьми отсюда: https://github.com/Open-GTO/Open-GTO...rmatnumber.inc
    Последний раз редактировалось ziggi; 08.09.2018 в 11:01.

  3. #3
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Есть ещё такой вариант
    1. stock AddCommasToInt(number, delimiter[2] = ".")
    2. {
    3. new int_string[10+3+1+1];
    4.  
    5. format(int_string, sizeof(int_string), "%d", number >= 0 ? number : -number);//Если число положительное - запишем его в обычном виде. Иначе - добавим ещё один минус, дабы сделать его положительным
    6.  
    7.  
    8. new value = strlen(int_string);// Запишем в value размер строки с числом
    9.  
    10. switch(value)
    11. {
    12. case 4..6: // Если переданное число содержит от 4-х до 6-и символов, добавим один разделитель
    13. strins(int_string, delimiter, value-3,1);
    14. case 7..9: // Если от 7-и до 9-и - два разделителя
    15. strins(int_string, delimiter, value-3,1),
    16. strins(int_string, delimiter, value-6,1);
    17. case 10..12: // Если от 10-и до 12-и - три разделителя
    18. strins(int_string, delimiter, value-3,1),
    19. strins(int_string, delimiter, value-6,1),
    20. strins(int_string, delimiter, value-9,1);
    21. }
    22.  
    23. if(number < 0) strins(int_string, "-", 0); // Если число отрицательное, вернём ему минус
    24. return int_string;
    25. }

    Только нужно будет добавить дополнительные условия, в зависимости от того, каким может быть максимальное число
    Последний раз редактировалось DeimoS; 08.09.2018 в 11:23.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  4. #4
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Есть ещё такой вариант
    1. stock AddCommasToInt(number, delimiter[2] = ".")
    2. {
    3. new int_string[10+3+1+1];
    4.  
    5. format(int_string, sizeof(int_string), "%d", number >= 0 ? number : -number);//Если число положительное - запишем его в обычном виде. Иначе - добавим ещё один минус, дабы сделать его положительным
    6.  
    7.  
    8. new value = strlen(int_string);// Запишем в value размер строки с числом
    9.  
    10. switch(value)
    11. {
    12. case 4..6: // Если переданное число содержит от 4-х до 6-и символов, добавим один разделитель
    13. strins(int_string, delimiter, value-3,1);
    14. case 7..9: // Если от 7-и до 9-и - два разделителя
    15. strins(int_string, delimiter, value-3,1),
    16. strins(int_string, delimiter, value-6,1);
    17. case 10..12: // Если от 10-и до 12-и - три разделителя
    18. strins(int_string, delimiter, value-3,1),
    19. strins(int_string, delimiter, value-6,1),
    20. strins(int_string, delimiter, value-9,1);
    21. }
    22.  
    23. if(number < 0) strins(int_string, "-", 0); // Если число отрицательное, вернём ему минус
    24. return int_string;
    25. }

    Только нужно будет добавить дополнительные условия, в зависимости от того, каким может быть максимальное число
    Вот здесь есть ещё: http://wiki.sa-mp.com/wiki/AddThousa...ors#Definition

  5. #5
    Аватар для Josan_Solomon
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.08.2018
    Сообщений
    59
    Репутация:
    2 ±
    Увы, format и valstr, как я уже сказал, не способны справиться с большими числами. Пробовал тэг long (хотя еще ни разу не встречал его в pawn), но снова не то. Как можно обойти это, чтобы работать с большими числами?

  6. #6
    Аватар для Batya_Montes
    Пользователь

    Статус
    Оффлайн
    Регистрация
    26.02.2017
    Адрес
    0x
    Сообщений
    163
    Репутация:
    13 ±
    Цитата Сообщение от Josan_Solomon Посмотреть сообщение
    Увы, format и valstr, как я уже сказал, не способны справиться с большими числами. Пробовал тэг long (хотя еще ни разу не встречал его в pawn), но снова не то. Как можно обойти это, чтобы работать с большими числами?
    а ничего что твое число "123456789000" выходит за рамки возможностей 32-битного языка и для него уже нужен тип bigint, коего нет в павн?
    0x

  7. #7
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Как уже выше заметили, это невозможно из-за ограничений языка.
    Тут два выхода есть:
    1) Хранить число как строку
    2) Разбить число на 2 переменные
    Оба варианта потребуют написания своего алгоритма для обработки чисел.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  8. #8
    Аватар для Josan_Solomon
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.08.2018
    Сообщений
    59
    Репутация:
    2 ±
    Неожиданное фиаско.. А что по вашему более экономно?

    - - - Добавлено - - -

    Цитата Сообщение от ziggi Посмотреть сообщение
    [url]Там все ссылки не работают, возьми отсюда: https://github.com/Open-GTO/Open-GTO...rmatnumber.inc
    Скорее всего, это ошибка, но все же, надежда умирает последней. В примере исходника той ссылки есть такой код:
    1. thousand seperator - char between thousands
    2. new mynumber = 5000000000;
    3. FormatNumber( myfloat ); // gives 5 000 000 000
    4. FormatNumber( myfloat, 0, ',' ); // gives 5,000,000,000
    5. FormatNumber( myfloat, 0, 0 ); // gives 5000000000

    Число в нем - 5 миллиардов, что превышает 32 битное 2,147,483,648. Это рабочий пример, или Slice просто не доглядел?

  9. #9
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от Josan_Solomon Посмотреть сообщение
    Неожиданное фиаско.. А что по вашему более экономно?

    - - - Добавлено - - -


    Скорее всего, это ошибка, но все же, надежда умирает последней. В примере исходника той ссылки есть такой код:
    1. thousand seperator - char between thousands
    2. new mynumber = 5000000000;
    3. FormatNumber( myfloat ); // gives 5 000 000 000
    4. FormatNumber( myfloat, 0, ',' ); // gives 5,000,000,000
    5. FormatNumber( myfloat, 0, 0 ); // gives 5000000000

    Число в нем - 5 миллиардов, что превышает 32 битное 2,147,483,648. Это рабочий пример, или Slice просто не доглядел?
    Я бы не сказал, что 2,147,483,648 - предел 32 битного числа, скорее 31 битного (ибо самый старший бит - показатель знака). Для 32 битного это число в два раза больше. К тому же, названия переменной и переданного аргумента не совпадают. Название переменной, переданной в качестве аргумента, содержит слово float. Не трудно догадаться, что 32 битный float может содержать довольно большое значение из-за стандарта хранения чисел с плавающей точкой.

    UPD: Да, документация в файле неточная, поэтому советую смотреть пример в теме, там вроде бы хороший пример.
    Последний раз редактировалось VVWVV; 09.09.2018 в 04:19.

  10. #10
    Аватар для Josan_Solomon
    Пользователь

    Статус
    Оффлайн
    Регистрация
    08.08.2018
    Сообщений
    59
    Репутация:
    2 ±
    Промелькнула шальная мысль хранить значение во float(а потом убирать точку), потом дошло что сам язык 32-х битный и ничего с этим ограничением уже не поделаешь. Как печально.. А как вы хранили бы большие числа?

    - - - Добавлено - - -

    И какое максимальное значение у float? Не нашел список диапазона значений для pawn

    - - - Добавлено - - -

    Поэкспериментировал и не нашел четкого ограничения, но увы, точность стала пропадать

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

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

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

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

Ваши права

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