Isolating digits in a number
BlitzMax Forums/BlitzMax Programming/Isolating digits in a number
| ||
I need to optimize some code, and so I need a really efficiant way of isolating numbers in an integer. Right now I am doing this, which is really more cpu intensive than it should be:a = 1234 Print a Mod 10 Print (a / 10) Mod 10 Print (a / 100) Mod 10 Print (a / 1000) Mod 10 Any suggestions? Last edited 2011 |
| ||
I've though about changing the INT to a STRING, then it would be easy to isolate characters- however then I need to change those back to INTs. Would all that switching back and forth be any better? Last edited 2011 |
| ||
The first conversion to a string would be the time sync so depending on the length of the number you might see performance gains... converting back can be done by either shoving the character into an int, which will cause bmax to the the conversion, or (I'm not sure how to do this in bmax properly since it wants to auto convert things for you, but this would work in C... I'm guessing use Asc() but I don't know what overhead that might have...) just adjust the int value of the ascii character (e.g. subtract 48 since you know they're all int ascii chars representing actual integers). That would keep the conversion from char to the right int very simple (just 1 subtraction after extracting it from the array of characters which would also be very quick) Last edited 2011 |
| ||
is this any faster?Function getDigit(n,i) pow=10^i a = n/pow b = n/(pow*10) Return a-b*10 End Function n = 12345 For i=0 To 4 Print getDigit(n,i) Next |
| ||
Are negative numbers allowed? Anyway, I would do this:a = 1234 Local aTemp = Abs(a) Repeat Print aTemp Mod 10 aTemp :/ 10 Until aTemp = 0 |
| ||
Hey, i assume you want to use the isolated values in some calculation? Do you already know the length of the decimal value? If not, then an attempt like Floyd's may be the only way to go. So... Bmax compiler is smart enough to use idiv (Interger division) in your routine: Ex: a=1234 b=(a/1000) mod 10 Here is the assem code: mov eax,1234 mov ecx,1000 cdq idiv ecx cdq mov eax,0 You'll notice that there are no calls to external routines, or any other of that kind of overhead. (Also note in this limited example all variables are from the register...) If your actually going to print the values then you will have overhead from: call _bbStringFromInt AND call _brl_standardio_Print No matter what you try to do. We will have to wait and hear from other geniuses out there, but I don't believe your going to find a "faster" routine for doing what your trying to accomplish? Maybe someone can prove me wrong. -------------------------------------------------------- Update Edit: There is a efficient routine (using no division/etc) for doing exactly what you need, but I'm having difficulty locating it. I'll update further once I find the routine. ------------------------------------------------------- Another Update: I can convert this to hex quickly. LOL (Sorry, I couldn't resist.) a=1234 For i:Int=0 To 7 Print ((a Shr (i * 4)) & 15) Next ------------------------------------------------------- Not to be nosey, but why are you doing this? :) Last edited 2011 Last edited 2011 Last edited 2011 |
| ||
Im a bit curious about the application of this too :d Cant really think of any situation where this would be critical for execution speed, except for perhaps an euler problem or two. |