Search Unity

Possible Internal rounding of small floats

Discussion in 'Scripting' started by Technokid2000, Oct 17, 2019.

  1. Technokid2000

    Technokid2000

    Joined:
    Dec 18, 2016
    Posts:
    36
    I'm having issues with some of my code:
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class TimeController : MonoBehaviour {
    7.     [HideInInspector]
    8.     public float money;
    9.  
    10.     public float earningsMultiplier = 1;
    11.     public float timeBetweenSaves = 10;
    12.  
    13.     public Text t;
    14.  
    15.     TimeSpan timeDifference;
    16.  
    17.     private void Start()
    18.     {
    19.         timeDifference = DateTime.UtcNow - DateTime.Parse(PlayerPrefs.GetString("lastSavedTimeAndDate"));
    20.         PlayerPrefs.SetString("totalMoney", (getCurrentMoney() + timeDifference.TotalSeconds * earningsMultiplier).ToString());
    21.      
    22.         InvokeRepeating("SaveDataPeriodically",timeBetweenSaves, timeBetweenSaves);
    23.  
    24.         money = getCurrentMoney();
    25.     }
    26.  
    27.     private void Update()
    28.     {
    29.         money += Time.deltaTime * earningsMultiplier;
    30.         PlayerPrefs.SetString("totalMoney", money.ToString());
    31.  
    32.         //Keep last saved time up to date (HA! Unintentional puns rule XD!)
    33.         PlayerPrefs.SetString("lastSavedTimeAndDate", DateTime.UtcNow.ToString());
    34.  
    35.         t.text = "Current Credits: " + money.ToString();
    36.     }
    37.  
    38.     IEnumerator SaveDataPeriodically() { PlayerPrefs.Save(); return null; }
    39.  
    40.     public float getCurrentMoney() { return float.Parse(PlayerPrefs.GetString("totalMoney")); }
    41.     public void PurchaseItem(float cost) { money -= cost; }
    42.     public bool CanAfford(float unitCost) { if (money >= unitCost) { return true; } return false; }
    43. }
    44.  
    The issue seems to be this line here:
    Code (CSharp):
    1. money += Time.deltaTime * earningsMultiplier;
    For some reason, it seems to be rounding Time.deltaTime * earningsMultiplier to zero if I set earningsMultiplier to something smaller than 1. Even 0.9 seems to bug out a bit. Does anyone know why it would be rounding this? Money is supposed to increment over time (This is code for something similar to a cookie clicker game where money increments over time), but at the moment due to this bug it stays where it is if the multiplier is small enough. I cannot continue my game until this bug is sorted. Any suggestions are welcome :)

    Edit: It does not round Time.deltaTime * earningsMultiplier to zero. Instead, it just doesn't add the tiny value of Time.deltaTime * earningsMultiplier to money for some reason. E.g. 300,000.7 + 0.00016 = 300,000.7 according to unity. You can see where the bug occurs. Yet, for example, 300,000.7 + 0.016 = 300,000.716
     
    Last edited: Oct 17, 2019
  2. Check the Single.ToString format section: https://docs.microsoft.com/en-us/dotnet/api/system.single.tostring?view=netframework-4.8
    Only the text where you were using ToString() should be affected BTW.
     
  3. Technokid2000

    Technokid2000

    Joined:
    Dec 18, 2016
    Posts:
    36
    I've tested that, but even when I put out to the console it still has the same issue.
     
  4. Tested what? Did you try the
    Code (CSharp):
    1. money.ToString("G", CultureInfo.InvariantCulture);