Search Unity

Very high int values turning negative

Discussion in 'Editor & General Support' started by Yash987654321, May 4, 2015.

  1. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    Hi
    When debugging i just found that because of money multiplier upgrade (which I won't remove) The reward goes crazy high and the text field starts to showing it negative. I don't mind in to going it in E and all but i dont want then negative
     
  2. Zaddo67

    Zaddo67

    Joined:
    Aug 14, 2012
    Posts:
    489
    Numbers will overflow to negatives if they get larger than the biggest value. Under the hood, numeric arithmetic is just simple bit wise manipulation. If you numbers may overflow, then you need to trap this in your code.

    http://en.wikipedia.org/wiki/Integer_overflow
     
  3. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    Yeah, that kind of happens. It turns out ints are actually finite, in fact it's only 31 bits (plus the signed bit). If you only want positive numbers then you can get the full 32 bits of range using a uint (unsigned integer), or you can get your money's worth by using a long which is 63 bits.
     
  4. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Sounds like maybe you're exceeding the maximum value that a signed integer can hold. A temporary fix would be to use an unsigned integer, but a true fix might be either to scale down your money so that you don't approach the limits of numeric data types... or you can write a system of string numbers.

    change 1000 to be "1000" and when you're doing math, do it 1 place at a time like you would by hand. Then you don't have to worry about limits.

    Examples!

    Code (CSharp):
    1. string cost = "1000";
    2. string wallet = "2000";
    3. Debug.Log(strSub(wallet, cost, 0));
    4.  
    5. public int strSub(string a, string b, int place)
    6. {
    7.     return int.Parse(a.substring(place, 1)) - int.Parse(b.substring(place, 1));
    8. }
    Have methods to add and subtract from different places in your string, ultimately looping through and adding or subtracting each place. In the example I posted, if you subtract "4" and "3" you would get back 1, and you can put that in the string at the string index that was being subtracted. If you subtract "4" and "5" you will get back -1, so you know you need to handle a carry over.

    Implement a string math system like I have in some projects and your number limit will be the maximum length of a string :)
     
    GibTreaty likes this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Check out the BigInteger class. Just use with caution, its plausible to run out of memory this way.

    As an alternative you can chain ints together. Or you can use the int64 if you just need a little bit more precision.
     
  6. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I did that for a game once. The first integer was the enemy health, the second integer was the number of health bars this enemy had, and the third integer was the number of those sets. So...

    Monster health was ~30,000
    Monster could have ~30,000 bars of health that were ~30,000 each
    Monster could have ~30,000 sets of ~30,000 bars that were ~30,000 each

    I found string math to be a more interesting solution.
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    My chaining was pretty similar. Each int64 represents 18 digits. If you go over on an individual int64 then you add 1 to the next int64. Limiting it to 18 digits meant you still had space to detect the overrun.

    My implementation is still over on Answers if anyone wants to try their luck with the search engine
     
  8. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    Hitting the limit is poor game/logic design.

    Manipulating strings for math is also poor design.
     
    Ostwind and Fuzzy like this.
  9. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    I just converted int to int64 and it worked!
    edit- now i will need to test app again as if i do not clear the save the int64 won't read normal ints. I saved them with ToString. and loaded from Convert
     
  10. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    ok now when i try to multiply reward it gives me that i am missing a cast. I tried most of them.
    I am multiplying a int64 to a float
    don't ask me why
     
  11. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    solved!
     
    Master-Frog likes this.
  12. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    i just discovered a bug int 64 do not save in inspector
     
  13. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    That's probably a feature, not a bug. I doubt int64 would be serializable by default.
     
  14. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    I also thought so. But i made it a serializeable field still the same result
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    SerialiseField doesn't make something serializable. You will also need a property drawer and maybe serialisation call backs. There is probably scripts around for it already.
     
  16. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    You could also just use smaller numbers. ;)
     
    Devil_Inside and Kiwasi like this.
  17. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,175
    Why are you multiplying to a float? A float only has seven digits of precision and you will be losing most of your number in the process. You should try multiplying to a decimal. It has about 28 digits of precision and is intended for financial math.

    https://msdn.microsoft.com/en-us/library/364x0z75(v=vs.80).aspx
     
    Last edited: May 4, 2015
    Dustin-Horne likes this.
  18. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    leave it its solves and my game is working
     
  19. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    I could also just use larger number :p
     
  20. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,175
    I don't consider math results where you lose entire parts of the number to be working.
     
    angrypenguin and zombiegorilla like this.
  21. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    i don't know what I was thinking while making the game... I just collected garbage. I used bad ways like adding 0.001 and round it when needed. There where many ways to do that. In a rush i picked this
     
  22. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    384
    If int overflows use Long. if you write "int number = 3000000000" (3 billion), you will get error or negative value since it will turn into garbage.
    If you use "long number = 3000000000L" it will be okay, you can go as high as 8-9 quintillion, if I remember right. (9.000.000.000.000.000.000)

    https://msdn.microsoft.com/en-us/library/ctetwysk.aspx (Don`t forget to put "L" after the number, as you put "f" after float)
     
  23. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    If negative numbers don't make sense for whatever you're doing, using uint instead of int may help. This will actually double the max value before it would rollover to 0.
     
  24. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Well what is your suggestion for displaying a number that has over a thousand digits? :p

    Look at all of you posting reasonable answers. Why can't people dream of having numbers in their games with as many digits as there are characters in Artamène ou le Grand Cyrus?


    Pff look at that scrub number. It only has 19 digits.

     
    Last edited: May 4, 2015
    frosted likes this.
  25. Grimwolf

    Grimwolf

    Joined:
    Oct 12, 2013
    Posts:
    296
    I think a better question is, under what circumstances do you have to?
    There's certainly no reason a monster needs to have 27,000,000,000,000 health.
     
  26. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,175
    What's the point when you're simply going to throw away precision beyond seven digits? :p
     
  27. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    You don't have to if it's all stored as a string ;) It will slow your program down considerably if you were operating on the values in real time, but it's doable!

    Hey, maybe I only made that initial suggestion so I could in the end take a shot at blizzard for having monsters with more than 27,000,000,000 health in diablo 3. Did you consider that? :3

    I must say it feels wonderful to have so many people say it's poor design. I like when developers screw up the IP they've taken from other developers. The Activision-blizzard south-WoW team has no business with ARPGs, especially the diablo series.

    --edit

    Don't tell me it doesn't make you feel superior to computers when you can write out 1,000,000,000,000,000,000,000,000,000,000
    + 1,000,000,000,000,000,000,000,000,000,000
    = 2,000,000,000,000,000,000,000,000,000,000

    but a computer cannot :p
     
    Vaupell, Master-Frog and Wacky-Moose like this.
  28. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    384
    Well, I think in Wow:Mists of Pandaria some bosses had such a huge numbers due to fact that blizzard was always increasing stats from Vanilla.
     
  29. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    Actually there is. To show how much badass your character is to give like 100,000,000,000 damage while fight being of reasonable length (i.e. enemy doesn't die in 2 hits).
     
  30. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    Tell that to Blizzard!
     
  31. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I have a suspicion that they may be faking it. You can't change your equipment in Greater Rifts where these absurd numbers are, so there's a chance they might scale everything down and pad some random text onto the end.
     
    Wacky-Moose and Kiwasi like this.
  32. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Talking of use cases, idle games are the most common use I've seen for high precision numbers. It actually becomes quite common to add a vey small number to a very large one there.

    Many noobs jump on Unity thinking idle games have to be the easiest to make, then run into issues with data precision or overflow.
     
    Tomnnn likes this.
  33. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    In the last WoW expansion they did the logical thing and wound everything back to smaller numbers. 1,000,000 became 10,000 etc. It was still at the same level it initially was because everything was scaled back, it was just a significantly smaller and more optimized number.

    Displaying a string number is fine, but doing string splits/parsing etc seems ott. Its a fun solution no doubt, but every string operation is added overhead (trivial amount sure... but its still there).
     
  34. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I get the feeling it's that most people who were more recently self-taught don't get a lesson on data structures. It's something most people who went to school understand pretty well, so they don't actually talk about it, which leaves people who were self-taught not knowing that variables are finite.
     
  35. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Working with string made a difference of my program running for 3 seconds vs it running for 34 minutes. With all of the logging information off it ran almost instantly. I didn't even log anything until it finished, it just added log information to an array of strings and then saved it at the end.

    In java, string anything seems to delay things significantly.
     
  36. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Maybe. But maybe not.

    I'm self taught. One of the early things I did was read through the MSDN documentation on each of the primitive types. Its pretty apparent what the data limitations are from a quick skim. Sure I don't remember the limits, but I know they are there if I ever need them. I would have approached this problem by first reading the documentation on int.

    Maybe its just my training in chemical engineering. Maybe its my religious background. But reading the manual is pretty deeply ingrained in me. As is a distrust in an infinite container. If I can't build a tank that holds an infinite amount of liquid, why should a computer be any different.
     
    GarBenjamin likes this.
  37. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I'm also old enough to remember the Y2K bug, where every computer in the world was brought to its knees because the early programmers decided to only include two digits of precision on dates. So maybe anyone younger then 20 does have an excuse for not to have an in built appreciation for the limitations of data types.

    Edit: And lets hope that our grand kids remember to fix this before the year 10,000 messes it all up again.
     
    MD_Reptile likes this.
  38. minionnz

    minionnz

    Joined:
    Jan 29, 2013
    Posts:
    391
    27,000,000,000,000 could be stored as 27,000 * 1,000,000,000.

    You have int, uint, long, ulong - if you need more than that, I'd argue you're doing something wrong.
     
  39. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    I remember y2k, and how it was a completely blown out of proportion. Great time to be a dev though, and it was a great way to force old redundant systems to be updated.
     
  40. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I can't imagine most people start with MSDN references. I tend to think the wording is overly technical (granted it's never technical enough when you need it), and it's easy to get lost in parts that aren't what people actually use.

    I would imagine people usually start with tutorials that just say "this is for integers, this is for decimals, and this is for letters" and aren't given much understanding of what they are and how they work. It won't be until they get bit in the ass by it that they really start to understand how it all works.
     
    Kiwasi likes this.
  41. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    BigInteger requires .NET 4, although you could go pull the code files from the mono source code and put it in yourself.

    That being said, why are you using whole numbers for money anyway? You should be using Decimal (never float for currency because it's approximate). If you're only dealing with whole numbers, then use int64 (long). There's no reason it shouldn't be serializable, it's a primitive. Just make sure you have a property for it as stated earlier and not just a field.
     
    Kiwasi and Ryiah like this.
  42. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Ahhhhhhh y2k... taking me way back haha, you guys ever get that silly y2k bug Screensaver that was pretty popular back then?

    Anyway on topic I've never needed anything but int and float types, but then again I've never worked for blizzard haha

    Edit: maybe you guys will recognize this -

     
    Master-Frog likes this.
  43. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    That's the trouble with randomly browsing MSN. That's the second time in the last month I've tried to implement a new feature and wondered what is going wrong.
     
  44. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    It certainly made cs280 a ton of fun. We had to use an extremely outdated g++ compiler so a lot of nice things weren't available :c
     
  45. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You know what, if Unity upgraded there mono version storage container into something with more then binary precision we could be on to .NET 4.5 by now. Shouldn't take much more then a magic button to let 2.0 become 4.5. Its just over twice as high. :)
     
  46. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    There's a version selector to help out with that. If it doesn't show .NET 3.5 you can't use it (natively) in Unity.
     
    Dustin-Horne likes this.
  47. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yeah, I figured that out eventually. It was just not where I look first time around. I'm still very much learning different coding techniques that are out there. So my first place to look was "You've done something wrong in implementing this language feature", not "This language feature is more advanced then anything included in Unity".

    Needless to say, now I check versions.
     
  48. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    384
    27,000,000,000,000 could be stored in array of size 14. Each index per digit. This helped me to create factorial algorithm to count even 10 000+ factorial which has 35 000+ digits.
     
  49. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    In my game a food needs 27,000,000,000,000 calories
     
  50. Yash987654321

    Yash987654321

    Joined:
    Oct 22, 2014
    Posts:
    729
    breaking them = nonsense.
    Saving Array and reloading = nonsense (I can save and load though)