- Home /
Questions about numbers, C#
Hello
i am doing a game that depends on Numbers by using C# and unity.
can you answer these questions please?
1-How can i make comma system? (10000 to 10,000)
2-when the number pass 100000 i want to display it as 100k and treat it as 100000 (kilo, mega, giga etc) How can i do that?
3-how can i keep the number as int but i can pass the last value for int? (i think its 2 bilion or something)
Thank you very much
any help for point 2 please and how to do calculation on it ? :(
Answer by Kiwasi · Oct 06, 2014 at 06:53 AM
I wrote you a big long answer that would do the job. Then my internet cut out when I hit post. Rather then rewrite it I'll sum it up here.
For the large number precision
Use int64, twice as many bits, twice as much data
Build a custom struct
Chain multiple int64 together. Each represents 18 digits of your number
Implement the + and subtract operators on your struct. Adding is int64 by int64, but you have to watch for overflow and add 1 to the next int64 up the chain. Subtraction is the opposite.
For display purposes
Override the ToString method of your struct
Find the first int64 with a non zero value
Calculate the log1000 to work out how which prefix index to use. Add an extra 9 for each int64 going down the chain
Implement a static array to grab the prefixes out of, based on the index calculated above
Round the int64 down to the first 3 digits or so
Convert the value to a string (put commas in if you like), attach the prefix and return
Good luck implementing all that. But its the best way to do your job. If I get really bored I might come back and write the struct again. But I have no use for it in my current project.
Edit: Some code. Apparently its a slow night tonight
public struct intchain {
int64 a;
int64 b;
// Probably want this bigger then 3
private static string[] prefixes = new string[3]{"","kilo", "mega"};
public intchain (int a, int b){
this.a = a;
this.b = b;
}
public static intchain operator + (intchain a, intchain b){
if (a.a + b.b >= Mathf.pow(10,18){
return new intchain (a.a + b.a + 1, a.b + b.b);
}
return new intchain (a.a + b.a, a.b + b.b);
}
// Implement subtraction here. Same principle
public override string ToString (){
int prefix = 0;
int value = 0
if (a==0){
prefix = (int)Mathf.Log(int32,b);
value = (int)(b/Mathf.pow(1000,prefix-1);
} else {
prefix = (int)Mathf.Log(int32,a);
value = (int)(a/Mathf.pow(1000,prefix-1);
prefix += 9;
}
// You could format value here as in some of the other answers if you like.
return value.ToString() + prefixes[prefix];
}
}
Plus my usual warning about not ever having compiled this, or even done a thorough check for typos. Not sure how well Mathf will take to being handed int64 either. If that doesn't work then you can use multiple int (ie int32).
I assume you are familiar enough with using documentation to figure out what everything does. If not ask, I'll try help out.
NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!!!!!!!!!!
i needed the code :( its easier for me to understand it :(((((((
i am trying to understand ur summary
Thank you very much for your answer
Believe me, I was disappointed too. It was relatively complex to put together.
Okay, is there any chance you could explain this to me? I'm having a hard time trying to wrap my head round it, feel kind of overwhelmed haha...
Sure at the heart of this struct is an int64 chain. The idea is that each int64 in the chain holds 18 digits of data. As you overflow one each int64 you add 1 to the next int. essentially the same as ones, tens and hundreds in grade school math.
Answer by smallbit · Oct 05, 2014 at 05:36 AM
1) This I do by formating the string I display in the screen I cannot access my code now but it was something like this - > .ToString("#,##0.00") . Will update later. When any problems google c# thousand comma separator.
2) I would do is by simple if statement adding as many ifs you need
if(score<100000)
myStringToDisplay = result.ToString("#,##0.00");
else
myStringToDisplay = "100k";
3) I believe its like trying to put 2 liters of water into 1 litre bottle. You simply cannot do that. Use long, or if your number gets really long varchar (keep it in text format if you dont do too many aritmetical operations on the number) or finally check the BigInteger structure from System.numerics library.
Thank you i understood point 1 and 3.
but for changing the number from 999 to 1k, how can i do calculation in that variable?
i mean if i have now 1.2k and i bought something for 400 how can i make the result 800?
I showed just how to display numbers in GUI or wherever you need to, you will be storing them keeping the proper value as i.e. 1200000 than you perform the operations on that.
Answer by Habitablaba · Oct 05, 2014 at 06:29 AM
This is a really great place to start as far as formatting the numbers as strings is concerned.
For the issue of storing really big numbers (and to a lesser extent, dealing with kilo, mega, giga, etc.), You could use an int for each order of magnitude. So you could have
int bytes; // just using bytes as an example.
int kilo;
int mega;
int giga;
public void Update()
{
bytes += 1; // or however you're increasing
if(bytes >= 999)
{
bytes = 0;
kilo += 1;
}
if(kilo >= 999)
{
kilo = 0;
mega += 1;
}
// etc...
}
You could get even more clever with it if you did something like the following:
public int[] currency = new int[6];
public void IncrementCurrency()
{
currency[0] += 1;
for(int i = 0; i < 5; ++i)
{
if(currency[i] >= 999)
{
currency[i] = 0;
currency[i + 1] += 1;
}
}
}
Obviously there are improvements that could be made around increasing currency by more than one each time, and making sure they remainder carries over after the shift up in magnitude.
Thank you i understood point 1 and 3.
but for changing the number from 999 to 1k, how can i do calculation in that variable?
i mean if i have now 1.2k and i bought something for 400 how can i make the result 800?
also if i am increasing by 7 for example it will be:
981 990 999 with out byte=0 it will be 1008
so there will be 8 lost
i hope this was clear.
so how can i avoid this problem?
Answer by OctoMan · Oct 06, 2014 at 02:53 AM
You need a variable that holds (holder) the whole integer.
increase it however you like and update whenever needed.
{
holder += 1;
kilo = (holder %1000);
mega = (holder/1000) %1000;
giga = (holder/1000000)%1000;
}
%1000 means it will never be higher than 1000 and if it is, it goes back to 0.
If you spend something spend it from holder and all values will be updated. Put this into a label or such and see what happends, then go and format that.
example:
GUI.Label (new Rect (0,0,200,50), giga.ToString() + " . " + mega.ToString() + " . " + kilo.ToString());
//highest first - not formatted yet
Thank you for answering, will try your answer as soon as possible
will there be a problem if i increase by 9 for example
so it will be
981 990 999 0 ins$$anonymous$$d of 1008 (so 8 will be lost)
also i want holder to have the highest number available.
which declaration has the highest one? i mean int,float etc
You have to use holder as a whole number the whole time. Increasing by 9 will do what you want.
Then your variables kilo, mega, giga doing the rest.
As you can see in the other post int64 is what you are looking for, since it can hold 18 digits.
You might be able to use decimal or long too.
decimals can hold 28-29 digits. http://msdn.microsoft.com/de-de/library/364x0z75.aspx
long is an int64bit. http://msdn.microsoft.com/de-de/library/ctetwysk.aspx
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Making a bubble level (not a game but work tool) 1 Answer
An OS design issue: File types associated with their appropriate programs 1 Answer
C# Number to binary 1 Answer