Search Unity

How to remove digits from my int value?

Discussion in 'Scripting' started by hizral, Mar 27, 2013.

  1. hizral

    hizral

    Joined:
    Apr 27, 2010
    Posts:
    568
    Hello there,

    would like to know is it's possible to remove digits from my int value, for example I have a int value that have 6 digits (example : 123456), can I take the 6 digits value and remove the last 2 digit so it become a 4 digits value (example = 1234). Would that be possible.

    I yes, how do I do that.

    Thank you.
     
  2. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    Not sure why you would need to but for the above example you could do (123456 - 456) / 1000 = 123
     
  3. wolfhunter777

    wolfhunter777

    Joined:
    Nov 3, 2011
    Posts:
    534
    One way I'm thinking of is that you convert the integer to string then treat the string as a char array (it is anyway). You'll just grab the first 4 value of the string and replace the current string. Then parse it back as integer.
     
    shkar-noori likes this.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Just divide by 100.

    --Eric
     
  5. hizral

    hizral

    Joined:
    Apr 27, 2010
    Posts:
    568
    Thank you all for the input. @wolfhunter777, yea did a few reading I can used array to do that, but not fully understand how to used array yet, @Eric5h5, wow never knew one of the solution is that simple.
     
  6. AntonQvarfordt

    AntonQvarfordt

    Joined:
    Mar 14, 2013
    Posts:
    27
    Neat computing tips & tricks: A computer calculates multiplication a lot faster than division. So using *0.01 would process faster than /100. The difference is actually pretty big.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Actually it's pretty small on a modern CPU.

    --Eric
     
  8. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    Evidence you should leave these micro-optimizations to the compiler..

    Attempting one billion divisions!
    Result 1234 took 939798 ticks!
    Attempting one billion multiplications!
    Result 1234 took 932269 ticks!
    Attempting one billion shifts!
    Result 1234 took 4974061 ticks!
    Press any key to continue . . .

    Code (csharp):
    1. using System;
    2. using System.Diagnostics;
    3.  
    4. namespace ConsoleApplication1
    5. {
    6.     class Program
    7.     {
    8.         static void Main(string[] args)
    9.         {          
    10.             var timer = new Stopwatch();
    11.             var result = 0;
    12.             var number = 123456;
    13.  
    14.             Console.WriteLine("Attempting one billion divisions!");
    15.             timer.Start();
    16.             for (int i = 0; i < 1000000000; i ++)
    17.                 result = number/100;
    18.             timer.Stop();
    19.             Console.WriteLine("Result {0} took {1} ticks!", result, timer.ElapsedTicks);
    20.  
    21.             timer.Reset();
    22.  
    23.             Console.WriteLine("Attempting one billion multiplications!");
    24.             timer.Start();
    25.             for (int i = 0; i < 1000000000; i++)
    26.                 result = (int)(number * .01);
    27.             timer.Stop();
    28.             Console.WriteLine("Result {0} took {1} ticks!", result, timer.ElapsedTicks);
    29.  
    30.             timer.Reset();
    31.  
    32.             Console.WriteLine("Attempting one billion shifts!");
    33.             var quotient = 0;
    34.             var remainder = 0;
    35.             timer.Start();
    36.             for (int i = 0; i < 1000000000; i++)
    37.             {
    38.                 quotient = (number >> 1) + (number >> 3) + (number >> 6) - (number >> 10) + (number >> 12) + (number >> 13) - (number >> 16);
    39.                 quotient = quotient + (quotient >> 20);
    40.                 quotient = quotient >> 6;
    41.                 remainder = number - ((quotient << 6) + (quotient << 5) + (quotient << 2));
    42.                 result = quotient + ((remainder + 28) >> 7);
    43.             }
    44.             timer.Stop();
    45.             Console.WriteLine("Result {0} took {1} ticks!", result, timer.ElapsedTicks);
    46.  
    47.         }
    48.     }
    49. }
     
    Last edited: Jul 22, 2015
    Korno likes this.
  9. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    Well, micro-optimization is always possible. Using 'framework' posted above;

    Attempting one billion divisions!
    Took 26412686 ticks!
    Attempting one billion multiplications!
    Took 23780163 ticks!
    Attempting one billion shifts!
    Took 31701097 ticks!
    Attempting one billion hardcode /10 long!
    Took 18764953 ticks!
    Attempting one billion hardcode /100 long!
    Took 18771787 ticks!
    Attempting one billion hardcode /1000 long!
    Took 18760335 ticks!

    20% quicker, but only divides by set amount. Range limits at;

    /10 : 0 <= x <= 1.342.177.280
    /100 : 0 <= x <= 1.677.721.599
    /1000 : 0 <= x <= 262.143.999
    /10000 : 0 <= x <= 1.310.719.999

    etc.

    Code (CSharp):
    1. using System;
    2. using System.Diagnostics;
    3.  
    4. namespace ConsoleApplication1
    5. {
    6.     class Program
    7.     {
    8.         static void Main(string[] args)
    9.         {        
    10.             Stopwatch timer = new Stopwatch();
    11.             int result = 0;
    12.             int number = 123456;
    13.             long numberLong = number;
    14.  
    15.             Console.WriteLine("Attempting one billion divisions!");
    16.             timer.Start();
    17.             for (int i = 0; i < 1000000000; i ++)
    18.                 result = number/100;
    19.             timer.Stop();
    20.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    21.  
    22.             timer.Reset();
    23.  
    24.             Console.WriteLine("Attempting one billion multiplications!");
    25.             timer.Start();
    26.             for (int i = 0; i < 1000000000; i++)
    27.                 result = (int)(number * .01);
    28.             timer.Stop();
    29.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    30.  
    31.             timer.Reset();
    32.  
    33.             Console.WriteLine("Attempting one billion shifts!");
    34.             var quotient = 0;
    35.             var remainder = 0;
    36.             timer.Start();
    37.             for (int i = 0; i < 1000000000; i++)
    38.             {
    39.                 quotient = (number >> 1) + (number >> 3) + (number >> 6) - (number >> 10) + (number >> 12) + (number >> 13) - (number >> 16);
    40.                 quotient = quotient + (quotient >> 20);
    41.                 quotient = quotient >> 6;
    42.                 remainder = number - ((quotient << 6) + (quotient << 5) + (quotient << 2));
    43.                 result = quotient + ((remainder + 28) >> 7);
    44.             }
    45.             timer.Stop();
    46.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    47.  
    48.             timer.Reset ();
    49.  
    50.             Console.WriteLine("Attempting one billion hardcode /10 long!");
    51.             timer.Start();
    52.             for (int i = 0; i < 1000000000; i++)
    53.                 result = (int)((numberLong * 6871947674) >> 36); // safe from 0 up to and including 1.342.177.280
    54.             timer.Stop();
    55.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    56.  
    57.             timer.Reset ();
    58.  
    59.             Console.WriteLine("Attempting one billion hardcode /100 long!");
    60.             timer.Start();
    61.             for (int i = 0; i < 1000000000; i++)
    62.                 result = (int)((numberLong * 5497558139) >> 39); // safe from 0 up to and including 1.677.721.599
    63.             timer.Stop();
    64.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    65.  
    66.             timer.Reset ();
    67.  
    68.             Console.WriteLine("Attempting one billion hardcode /1000 long!");
    69.             timer.Start();
    70.             for (int i = 0; i < 1000000000; i++)
    71.                 result = (int)((numberLong * 35184372089) >> 45); // safe from 0 up to and including 262.143.999
    72.             timer.Stop();
    73.             Console.WriteLine("Took {1} ticks!", result, timer.ElapsedTicks);
    74.         }
    75.     }
    76. }
     
  10. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    Hmm.. not sure why but I get very different numbers than you

    Attempting one billion divisions!
    Took 938506 ticks!
    Attempting one billion multiplications!
    Took 945456 ticks!
    Attempting one billion shifts!
    Took 6777885 ticks!
    Attempting one billion hardcode /10 long!
    Took 12609203 ticks!
    Attempting one billion hardcode /100 long!
    Took 12622182 ticks!
    Attempting one billion hardcode /1000 long!
    Took 12459758 ticks!

    Different processor architecture maybe - another reason to leave the optimizations to the compiler.
     
  11. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    Question:
    Solutions:
    How to recognize good programmer :D
     
  12. DuffyT

    DuffyT

    Joined:
    Dec 16, 2014
    Posts:
    37
    Haha, couple of months ago I needed something similar to display an amount of money (ex. 10 million versus 10000000). I took the easy 2 - minute route and made a class that divides by million/billion/trillion thinking I'd implement something else later, haven't touched it since and works like a charm. :p
     
  13. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    Possibly. I'm using the most recent mono version on linux atm, for compiling and running. On an i5-4670k.

    I changed the code a bit so the result is the sum of all calculations, to prevent it from optimizing it away etc. It made the standard divisions as quick as the multiplications, and everything a tiny bit slower.
    If I run the mono AOT compiler over it, nothing changes except for the hardcodes becoming an additional 70% quicker. (5M ticks versus plain division 25M and non-AOT 19M)

    Ran the same code (minor changes into a monobehaviour) in a unity build, and it's practically the same as on most recent mono in linux.

    I'm mighty interested in knowing what you're running it on, given the massive difference.
     
  14. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    Hmm now that is interesting. I am running on an I7-2600 so I doubt there's much difference there.

    The big one is that I'm on Windows running through the MS compiler that ships with Visual Studio 2013. I'll try running it through Unity and see what happens.
     
  15. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    Here's my results from Unity. Your hard code method is outperforming but not by a lot. The main takeaway for me is how slow my multiplication/division code runs in Unity's sandbox as compared to the console application coming out of Visual Studio - it's 60 times slower! I'm shocked.

    Attempting one billion divisions!
    Took 60602003 ticks!
    Attempting one billion multiplications!
    Took 51681038 ticks!
    Attempting one billion shifts!
    Took 142006032 ticks!
    Attempting one billion hardcode /10 long!
    Took 48874815 ticks!
    Attempting one billion hardcode /100 long!
    Took 48955529 ticks!
    Attempting one billion hardcode /1000 long!
    Took 52623455 ticks!

    EDIT: I wasn't doing this test correctly - I didn't build my Unity game into an executable. Here is the results from a runtime compiled version. Something very bizarre - the performance of the hardcoded methods actually got worse. The performance of division is still 30 times worse than what's coming out of VS.

    Attempting one billion divisions!
    Took 31653434 ticks!
    Attempting one billion multiplications!
    Took 20700862 ticks!
    Attempting one billion shifts!
    Took 47634917 ticks!
    Attempting one billion hardcode /10 long!
    Took 83387255 ticks!
    Attempting one billion hardcode /100 long!
    Took 83863405 ticks!
    Attempting one billion hardcode /1000 long!
    Took 84452969 ticks!
     
    Last edited: Jul 23, 2015
  16. Zuntatos

    Zuntatos

    Joined:
    Nov 18, 2012
    Posts:
    612
    ...It got slower by building it? What. How is that even possible? Unless you were running something else straining the processor. And I can't see how a double multiplication would be 4 times quicker than a long multiplication + long shift...

    Try a project with the code below, and we'll be sure. It's the one that stores all the results in the hope of preventing it from being optimized away of sorts. With that exact code, I got this in the output_log.txt (after cutting crap out):

    Attempting one billion divisions!
    Result 1234 Took 25164277 ticks!
    Attempting one billion multiplications!
    Result 1234 Took 25113807 ticks!
    Attempting one billion shifts!
    Result 1234 Took 33666410 ticks!
    Attempting one billion hardcode /10 long!
    Result 12345 Took 19513724 ticks!
    Attempting one billion hardcode /100 long!
    Result 1234 Took 19624001 ticks!
    Attempting one billion hardcode /1000 long!
    Result 123 Took 19455630 ticks!

    Code (CSharp):
    1. using System.Diagnostics;
    2. using UnityEngine;
    3.  
    4. class Program : MonoBehaviour
    5. {
    6.   private void Start ()
    7.   {
    8.     Stopwatch timer = new Stopwatch();
    9.     int number = 123456;
    10.     long numberLong = number;
    11.     long loops = 1000000000;
    12.     long AllResults = 0;
    13.  
    14.     UnityEngine.Debug.LogFormat("Attempting one billion divisions!");
    15.     timer.Start();
    16.     for (long i = 0; i < loops; i++)
    17.       AllResults += number / 100;
    18.     timer.Stop();
    19.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    20.  
    21.     AllResults = 0;
    22.     timer.Reset();
    23.  
    24.     UnityEngine.Debug.LogFormat("Attempting one billion multiplications!");
    25.     timer.Start();
    26.     for (long i = 0; i < loops; i++)
    27.       AllResults += (long)(number * .01);
    28.     timer.Stop();
    29.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    30.  
    31.     AllResults = 0;
    32.     timer.Reset();
    33.  
    34.     UnityEngine.Debug.LogFormat("Attempting one billion shifts!");
    35.     var quotient = 0;
    36.     var remainder = 0;
    37.     timer.Start();
    38.     for (long i = 0; i < loops; i++) {
    39.       quotient = (number >> 1) + (number >> 3) + (number >> 6) - (number >> 10) + (number >> 12) + (number >> 13) - (number >> 16);
    40.       quotient = quotient + (quotient >> 20);
    41.       quotient = quotient >> 6;
    42.       remainder = number - ((quotient << 6) + (quotient << 5) + (quotient << 2));
    43.       AllResults += quotient + ((remainder + 28) >> 7);
    44.     }
    45.     timer.Stop();
    46.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    47.  
    48.     AllResults = 0;
    49.     timer.Reset();
    50.  
    51.     UnityEngine.Debug.LogFormat("Attempting one billion hardcode /10 long!");
    52.     timer.Start();
    53.     for (long i = 0; i < loops; i++)
    54.       AllResults += (numberLong * 6871947674) >> 36; // safe from 0 up to and including 1.342.177.280
    55.     timer.Stop();
    56.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    57.  
    58.     AllResults = 0;
    59.     timer.Reset();
    60.  
    61.     UnityEngine.Debug.LogFormat("Attempting one billion hardcode /100 long!");
    62.     timer.Start();
    63.     for (long i = 0; i < loops; i++)
    64.       AllResults += (numberLong * 5497558139) >> 39; // safe from 0 up to and including 1.677.721.599
    65.     timer.Stop();
    66.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    67.  
    68.     AllResults = 0;
    69.     timer.Reset();
    70.  
    71.     UnityEngine.Debug.LogFormat("Attempting one billion hardcode /1000 long!");
    72.     timer.Start();
    73.     for (long i = 0; i < loops; i++)
    74.       AllResults += (numberLong * 35184372089) >> 45; // safe from 0 up to and including 262.143.999
    75.     timer.Stop();
    76.     UnityEngine.Debug.LogFormat("Result {0} Took {1} ticks!", AllResults / loops, timer.ElapsedTicks);
    77.   }
    78. }
     
  17. eisenpony

    eisenpony

    Joined:
    May 8, 2015
    Posts:
    974
    I'm really surprised by this. Division is now performing the best. I ran this test a dozen times because the results are so weird but I get approximately the same numbers every time - even after a fresh restart.

    Attempting one billion divisions!
    Result 1234 Took 61127390 ticks!
    Attempting one billion multiplications!
    Result 1234 Took 94618417 ticks!
    Attempting one billion shifts!
    Result 1234 Took 98620894 ticks!
    Attempting one billion hardcode /10 long!
    Result 12345 Took 122287644 ticks!
    Attempting one billion hardcode /100 long!
    Result 1234 Took 129082681 ticks!
    Attempting one billion hardcode /1000 long!
    Result 123 Took 131903149 ticks!

    EDIT Results from a Console Application using your code. Apparently there was some optimization being done since my numbers are much slower now. Still, the hardcoded methods underperform and the code in Unity is running about 10 times slower.

    Attempting one billion divisions!
    Result 1234 Took 6094277 ticks!
    Attempting one billion multiplications!
    Result 1234 Took 12787509 ticks!
    Attempting one billion shifts!
    Result 1234 Took 11564522 ticks!
    Attempting one billion hardcode /10 long!
    Result 12345 Took 15344659 ticks!
    Attempting one billion hardcode /100 long!
    Result 1234 Took 15310919 ticks!
    Attempting one billion hardcode /1000 long!
    Result 123 Took 15300337 ticks!
     
    Last edited: Jul 23, 2015
  18. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    This thread is old ..... and does not reflect the speed truth of any calculation in this example.
    The reason is for (long i = 0; i < loops; i++) as INT64 that takes longer than a AllResults += number / 100;
    Something like this give you more real results.

    Code (CSharp):
    1. for (long i = 0; i < loops / 1000; i++) {
    2.    AllResults += number / 100;  // repeated 1
    3.    AllResults += number / 100;  // repeated 2
    4.    AllResults += number / 100;  // repeated 3
    5.    ...
    6.    AllResults += number / 100; // repeated 1000
    7. }
    8.  
     
    Last edited: May 11, 2017