patternMinor
Converting base-10 numbers into base-26 letters
Viewed 0 times
intonumbersbaseconvertingletters
Problem
I'm writing something that basically takes a bunch of files and renames them into a nice format, such as
I suppose there are two different types of output for a base-10 to base-26 function such as this:
-
without a fixed-length result, e.g.: A, B, ... , Z, AA, AB, ... ZZ, AAA (notice that A is representing a 1 when it is the leading letter and the result is more than one letter in length, else it is representing a 0)
-
with a fixed-length result, e.g. AAA, AAB, ... , ZZY, ZZZ (A will always represent a zero, here)
Again, I've chosen to write it both ways and let the user decide what they want. With (2), you just have to count how many input numbers there are (the numbers that we're converting in the first place) and then use an appropriately-sized result. Obviously two characters (AA, AB, etc.) isn't enough to represent a million different numbers, so you'd have see if three letters could do it, then four, and so on. (To make this easier, you can just do
Number 1, though, proved to be a bit of a doozy since A-Z can represent 0-25 in some places and 1-26 in others. If A is 0, then Z is 25, but unless you want to use BA for 26, skipping A_, then you have to let A be equal to 1 where it is a leading character (e.g. AA, AB, etc.) when the result is not 1 character long (i.e. for the result of
pic_000.jpeg, pic_001.jpeg, etc. One of the options is to write the incrementation as letters, e.g. pic_aaa.jpeg, pic_aab.jpeg, etc. Also, is they are converting a set of pic_000s into a set of pic_aaas, then there's also an option to preserve the order of increments. In other words, if you deleted pic_000 through pic_117, then the pic_aaa set would start at pic_aen, not pic_aaa. It's a little weird, but I'm just trying to give the user lot of options so they can do whatever they want.I suppose there are two different types of output for a base-10 to base-26 function such as this:
-
without a fixed-length result, e.g.: A, B, ... , Z, AA, AB, ... ZZ, AAA (notice that A is representing a 1 when it is the leading letter and the result is more than one letter in length, else it is representing a 0)
-
with a fixed-length result, e.g. AAA, AAB, ... , ZZY, ZZZ (A will always represent a zero, here)
Again, I've chosen to write it both ways and let the user decide what they want. With (2), you just have to count how many input numbers there are (the numbers that we're converting in the first place) and then use an appropriately-sized result. Obviously two characters (AA, AB, etc.) isn't enough to represent a million different numbers, so you'd have see if three letters could do it, then four, and so on. (To make this easier, you can just do
resultLength = ceil(log(inputNumber)/log(26)) (not vb6 code, but you get the idea) I haven't written (2) yet, but I assume it will be pretty easy.Number 1, though, proved to be a bit of a doozy since A-Z can represent 0-25 in some places and 1-26 in others. If A is 0, then Z is 25, but unless you want to use BA for 26, skipping A_, then you have to let A be equal to 1 where it is a leading character (e.g. AA, AB, etc.) when the result is not 1 character long (i.e. for the result of
A, A is 0 Solution
First Point:
For multiple
Also, this may be trickier, given that something falling into the first case looks like it would also fall into the other two. However, unlike other languages, there is no
Second Point:
I know I'm not doing much in the way of efficiency (more just style, I think), but here's another. Regarding:
Since you assign
Sorry for not getting this all out at once. I'll continue to pick apart as I have time and add to this answer as needed...
For multiple
If/Else blocks, I prefer to use Select Case. I would just do this out of habit, though your check is small enough that it may not matter too much. Also, this may be trickier, given that something falling into the first case looks like it would also fall into the other two. However, unlike other languages, there is no
break required, and the Select block ends at the first case it comes to (like the If/Else would have).Select Case input
Case Is < 26 ^ 1:
resultLength = 1
Case Is < (27 * (26 ^ 1) - 1): 'ZZ represents (27*26) -1
resultLength = 2
Case Is < (27 * (26 ^ 2) - 1): 'ZZ represents (27*26^2) -1
resultLength = 3
End SelectSecond Point:
I know I'm not doing much in the way of efficiency (more just style, I think), but here's another. Regarding:
If (i = Index) And (Index > 1) And Int(asLong / 26 ^ (i)) = 1 Then
j = 26 ^ i
asLong = asLong - 26 ^ (i - 1)
Else
j = 26 ^ i
End IfSince you assign
j = 26 ^ i in both cases, why not just assign it before the If?j = 26 ^ i
If (i = Index) And (Index > 1) And Int(asLong / 26 ^ (i)) = 1 Then
asLong = asLong - 26 ^ (i - 1)
End IfSorry for not getting this all out at once. I'll continue to pick apart as I have time and add to this answer as needed...
Code Snippets
Select Case input
Case Is < 26 ^ 1:
resultLength = 1
Case Is < (27 * (26 ^ 1) - 1): 'ZZ represents (27*26) -1
resultLength = 2
Case Is < (27 * (26 ^ 2) - 1): 'ZZ represents (27*26^2) -1
resultLength = 3
End SelectIf (i = Index) And (Index > 1) And Int(asLong / 26 ^ (i)) = 1 Then
j = 26 ^ i
asLong = asLong - 26 ^ (i - 1)
Else
j = 26 ^ i
End Ifj = 26 ^ i
If (i = Index) And (Index > 1) And Int(asLong / 26 ^ (i)) = 1 Then
asLong = asLong - 26 ^ (i - 1)
End IfContext
StackExchange Code Review Q#13480, answer score: 2
Revisions (0)
No revisions yet.