Isolating digits in a number

BlitzMax Forums/BlitzMax Programming/Isolating digits in a number

Tachyon(Posted 2011) [#1]
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


Tachyon(Posted 2011) [#2]
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


ima747(Posted 2011) [#3]
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


Warpy(Posted 2011) [#4]
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



Floyd(Posted 2011) [#5]
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



Shortwind(Posted 2011) [#6]
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


zzz(Posted 2011) [#7]
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.