Int prices

Hey all,

If you are like me and prefer a more classic currency system using Gold Pieces or something you were probably annoyed with this being set up with floats when you only need ints. However, you still want to fine tune discounts. I have found the best way to do this is with int casting and Math.Round. It seems to be working fairly well for me, but someone smarter may be able to find a way to make it more accurate. So here is my code for GetPrice:

    private int GetPrice(StockItemConfig config)
    {
        if(isBuyingMode) return (int)Math.Round(config.item.GetPrice() * (1 - config.buyingDiscountPercange / 100)); //Apply buying discounts

        return (int)Math.Round(config.item.GetPrice() * (sellingPercentage / 100)); //Apply sell penalty
    }

I apologize for the single line if statements. I much prefer them if there really is only one line to worry about. I use 90% zoom on a 1440p monitor so I have all the room in the world.

Now as far as displaying the prices(the :n0 does similar to the n2 with the currency type that Sam used, just this displays no decimals but adds the commas for thousands, millions, etc):

    public void Setup(Shop currentShop, ShopItem item)
    {
        //All the other stuff
        priceField.text = $"{item.GetPrice():n0} G"; 
    }
1 Like

Nice. You could also use Mathf.RoundToInt()

1 Like

Hah! Yeah I forgot about Mathf having that one.
I assume they are properly rounding and not just cutting off the decimals. It seemed that way with the math of the discount percentages I was using. For this simple of a formula that should be plenty, but surely more complex calculations (like if we were doing skill checks and stuff with percentages but wanting to end up with an int) I would guess that the rounding would start drifting away from a true value if you went and did every piece of it by hand and then rounded at the end. Wrapping EVERYTHING in one of the rounders would be fine but I am getting at returning ints in various places that then get rounded again.

According to the documentation:

If the number ends in .5 so it is halfway between two integers, one of which is even and the other odd, the even number is returned.

but it does round up or down depending on the decimal (nearest integer)

Mathf.Floor and Mathf.FloorToInt returns the largest integer that’s smaller than the value (drops the decimals), and
Mathf.Ceil and Mathf.CeilToInt returns the smallest integer that’s greater than the value

2 Likes

This was my solution. One small issue i ran into was i had “autopilot” used an int for the sell percentage and was getting returns of 0 because the float was calcing wrong. at first i actually hard casted the sell percentage float to an int in the get price to fix it before realizing i was being silly and just fixed it to a gloat up top. i didn’t like mathf.round as i would prefer to always round in the players favor so i used CeilToInt.

    private float GetPrice(StockItemConfig config)
        {
            if (_isBuyingMode)
            {
                return Mathf.CeilToInt(config._item.GetPrice() * (1 - config._buyingDiscountPercentage / 100));
            }

            return Mathf.CeilToInt(config._item.GetPrice() * (1 - _sellPercentage / 100));
        }```
1 Like

Thanks for highlighting this. I would have missed this detail, as it goes against what I am used to for rounding. It is one of several common approaches for rounding a fraction of .5. Rounding - Wikipedia

If you allow the nit-picky remark: for negative numbers, these methods don’t just drop the decimals, as that would give a larger result.

You are correct. The ‘(drops decimals)’ comment was just something I threw in 'cos it popped into my head as I wrote that and I never gave it a second thought. Good catch

Privacy & Terms