@ArasI

Как сохранять и сокращать ОЧЕНЬ большие числа типа int?

Делаю кликер на андроид на Unity 2020, там большое получается число (в коде money). Число в ulong, а тем более в int не помещается, как сохранять числа с (к примеру) 100 нулями? У меня число сокращается, т.е. 100 000 отображаются как 100К. Также число сохраняется в PlayerPrefs. Мне надо как-нибудь сохранить огромное число (хорошо было-бы сохранить в 1 переменной чтобы не менять код с сокращением числа, но если по-другому нельзя, то подойдёт и в нескольких переменных). Как это сделать?

Код, в котором число (money):
public class Game : MonoBehaviour
{

    public Text moneyText;
 

    public int money;

    void Start()
    {
        money = PlayerPrefs.GetInt("money");

    void Update()
    {
        moneyText.text = FormatNumbers.formatNumber(money);
    }

    public void Click()
    {
       money++;
       PlayerPrefs.SetInt("money", money);
    }
}

Код с сокращением числа:

public static class FormatNumbers
{
    public static string[] format_name = new[]
    {
        "", "K", "M", "t", "q", "Q", "s", "S", "o", "n", "d", "U", "D", "T", "Qt", "Qd", "Sd", "St", "O", "N", "v", "c"
    };

    public static string formatNumber(float num)
    {
        if (num == 0)
            return "0";

        int i = 0;
        while(i+1 < format_name.Length && num >= 1000f)
        {
            num /= 1000f;
            i++;
        }
        return num.ToString("#.##") + format_name[i];
    }
    
}
  • Вопрос задан
  • 431 просмотр
Решения вопроса 1
vabka
@vabka
Токсичный шарпист
Варианта три:
1. Использовать double - тогда максимум у тебя будет примерно 1e308 (1 с 308 нулями)
2. Хранить число в виде двух чисел - значение и степень десятки Точность на больших числах будет низкая, но предела по сути нет - можно будет хранить числа вплоть 2^64*10^(2^64) (если использовать два long). Эту же методику можно и с double реализовать - получится ~10^308*10^(10^308), что ещё больше
3. Можно попробовать BigInteger - по памяти не эффективно, медленно, но зато точность идеальная.

Чтобы прямо весь код не переписывать - свое "особое" число ты можешь реализовать как структуру со всеми нужными операторами и операторами приведения типов.

Вот пример, без реализации операторов

struct ExponentialInteger
{   
    private readonly int value;
    private readonly int exp;
    
    //.ctor
    // operator +
    // operator -
    // operator *
    // operator /
    // operator implicit
    // operator explicit
    // IEquatable, IComparable, IFormattable
    // итд
    private static string[] suffix = new[]
    {
        "", "K", "M", "t", "q", "Q", "s", "S", "o", "n", "d", "U", "D", "T", "Qt", "Qd", "Sd", "St", "O", "N", "v", "c"
    };

    public override string ToString()
    {
        if (exp >= suffix.Length || exp < 0)
        {
            return $"{value}*10^{exp}";
        }
        else
        {
            return $"{value}{suffix[exp]}";
        }
    }
}

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
freeExec
@freeExec
Участник OpenStreetMap
Ну т.е. по сути игрок видит только числа от 0 до 1000, и жалуешься что long не хватает, а тут 10 бит за глаза.
Но если вы так за свой код переживаете, используйте BigInteger
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы