I am looking for help, ideas, etcetera on how to convert between two number bases.

to convert from decimal to binary divide the number by two and write the remainder from right to left until the result is zero

ex: 11/2 = 5, rem 1

5/2 = 2, rem 1

2/2 = 1, rem 0

1/2 = 0, rem 1

the binary number is 1011b. ("b" means "binary")

to convert from binary to decimal add the powers of 2's respectively to the positions of ones from rigt to left in the binary number

ex: 1001101b = 1*2^0 + 0*2^1 + 1*2^2 + 1*2^3 + 0*2^4 + 0*2^5 + 1*2^6 = 1 + 4 + 8 + 64 = 76

you will be able to convert from hex to decimal if you undersood the convertion of binary to decimal, it is made in the same way but the base is naturally 16.

the convertion of binary to hex is even easier, you consider every four bits (digits) of binary as one respective digit of hex

ex: (1010 0110 1001)b = A69h

please ask if i can help you some more...:alright:

ex: 11/2 = 5, rem 1

5/2 = 2, rem 1

2/2 = 1, rem 0

1/2 = 0, rem 1

the binary number is 1011b. ("b" means "binary")

to convert from binary to decimal add the powers of 2's respectively to the positions of ones from rigt to left in the binary number

ex: 1001101b = 1*2^0 + 0*2^1 + 1*2^2 + 1*2^3 + 0*2^4 + 0*2^5 + 1*2^6 = 1 + 4 + 8 + 64 = 76

you will be able to convert from hex to decimal if you undersood the convertion of binary to decimal, it is made in the same way but the base is naturally 16.

the convertion of binary to hex is even easier, you consider every four bits (digits) of binary as one respective digit of hex

ex: (1010 0110 1001)b = A69h

please ask if i can help you some more...:alright:

If you want the computer to do it, the general strategy is to 1) get the number in string form, 2) convert it to a suitable numeric form, and then 3) convert it to a string form.

=====

Conversion (of integers) to a numeric form works roughly like this:

Start with accumulator = 0.

For each digit from left to right, new accumulator = (base * accumulator) + converted-digit.

Each digit must be converted from its character value to its numeric value.

=====

Conversion (of integers) to string form works roughly like this:

Start with accumulator = number.

Generate digits from right to left by repeatedly applying these two steps:

1) Convert (accumulator mod base) to character value.

2) New accumulator = accumulator / base.

Stop when accumulator is 0.

=====

Conversion (of integers) to a numeric form works roughly like this:

Start with accumulator = 0.

For each digit from left to right, new accumulator = (base * accumulator) + converted-digit.

Each digit must be converted from its character value to its numeric value.

=====

Conversion (of integers) to string form works roughly like this:

Start with accumulator = number.

Generate digits from right to left by repeatedly applying these two steps:

1) Convert (accumulator mod base) to character value.

2) New accumulator = accumulator / base.

Stop when accumulator is 0.

Sorry I should have been more clear. What I was looking for was not so much the method to convert numbers but an idea on how to implement it in assembly. I had done some work useing a method like applecin said. I was told to use shifts instead , but could quite get what they were talking about.

I'm also trying something like base conversion for decimal to hexadecimal, and its rather easy (at least i think)

Opcodes.hlp says for div:

DIV - Divide

Usage: DIV src

Modifies flags: (AF,CF,OF,PF,SF,ZF undefined)

Unsigned binary division of accumulator by source. If the source

divisor is a byte value then AX is divided by "src" and the quotient

is placed in AL and the remainder in AH. If source operand is a word

value, then DX:AX is divided by "src" and the quotient is stored in AX

and the remainder in DX.

Read the values from AL and AH (this goes for any conversion using division) and go from there, at least this is how im going about implementing decimal to hexadecimal.

EDIT: By the way, this might help you a lot:

http://www.melabs.com/resources/articles/hexnumbers.htm

```
```

mov ax,75 ;73 is the number to divide by 16

mov bh,16 ;base 16

div bh

Opcodes.hlp says for div:

DIV - Divide

Usage: DIV src

Modifies flags: (AF,CF,OF,PF,SF,ZF undefined)

Unsigned binary division of accumulator by source. If the source

divisor is a byte value then AX is divided by "src" and the quotient

is placed in AL and the remainder in AH. If source operand is a word

value, then DX:AX is divided by "src" and the quotient is stored in AX

and the remainder in DX.

Read the values from AL and AH (this goes for any conversion using division) and go from there, at least this is how im going about implementing decimal to hexadecimal.

EDIT: By the way, this might help you a lot:

http://www.melabs.com/resources/articles/hexnumbers.htm

Sorry I should have been more clear. What I was looking for was not so much the method to convert numbers but an idea on how to implement it in assembly. I had done some work useing a method like applecin said. I was told to use shifts instead , but could quite get what they were talking about.

i think whoever said you should use shifts was assuming you knew the base before hand and could replace the slow "div" instruction with a few shifts. not used to doing division in assembly, so perhaps someone could help you in optimizing that.

anyhoo, for base conversions, we use the principle that any positive (integer) number can be expressed in the form of (a0)b^n+(a1)b^(n-1)+(a2)b^(n-2)+...+(an)b^0

where the number after 'a' is the index and the value of each element is an integer <b.

for example, in base ten, b is 10. the number 53 is:

(5)10^1+(3)10^0=53.

in base 2 (i.e. binary), pick a value for n which, when two is raised to its power, is greater than 53. e.g., log(53)/log(2)=~5.7. Round down because rounding up results in a number larger than the number to be converted, which means that the co-efficient of anything larger than 5, for a(x)=0 (i.e., you'd end up with a number like 000053).

So, we take this value of n, 5 in the example above, and raise 2 to the power of 5. Recurse down for co-efficients (sorry - that's unclear so i'll give an example):

(a0)2^5+(a1)2^4+(a2)2^3+...+(a5)2^0=53

So we start from the first element and work to the right.

a0*2^5=53... what is the largest value of a0? that is, what is the largest value for a0 such that (a0)*2^5<=53? a0=floor(53/32)=1.

so, assembly, that would translate to

mov ax,53

mov bh,32

div bh

The remainder, which is what we are now working with, is 21 - in ah. The integer portion is in al, which has the value 1. So, the first digit is one.

Next value of n. n=4

a1*2^4<=21

a1=1 R=5

n=3:

a2*2^3<=5

a2=0 R=5

n=2:

a3*2^2<=5

a3=1 R=1

n=1:

a4*2<=1

a4=0 R=1

n=0:

a5<=1

a5=1 R=0

Done!

therefore, the number 53, in binary, is 110101.

The algo, in pseudo code is thus (since i can't test it):

n=log(number)/log(base)

mov cx,n

@@:

mov ax,number

;do some exponential stuff here to get base^cx. probably easier to use FPU to multiply by the inverse of the base... anyway

mov bh,base^cx

div bh

;save al somewhere: it is the next digit

dec cx

shr ax,8 (get rid of al; put ah in its place)

jnz @B

btw, converting to binary is much easier: you can keep shifting the number left and keep testing the high bit for a "1"

I guess it would also be quite helpful if I provide some more info. The biggest thing I am tring to do is convert from base 16,10,8,2 to base 3. More spicificly balanced ternary http://perun.hscs.wmin.ac.uk/~jra/ternary/. I think this should help.

Thanks for the code jademtech.

Thanks for the code jademtech.

Here is some quick code to convert from a base that is a power of two into a dword (it uses MMX) - also untested due to lack of a computer that has MMX capabilities, not to mention an assembler, other than debug, if it can be called that :( :

that should do the trick... my bad. didn't end up using MMX instructions :) reading up on balanced ternary.

```
```

LOCAL bleh:DWORD

mov bleh,0

mov ebx,-n ;where 2^n=base that you are converting from. so, the negative value of n...

lea eax,strNum ;load a pointer in eax to the number to be converted

mov ecx,lenStr ;move the pointer to the end of the string using a zero-based offset (i.e. a 1-character number is 0, 2-characters is 1, etc.)

@@:

mov edx,[eax+ecx] ;get value at eax

add ebx,n ;where 2^n=base that you are converting from

and edx,0fh ;keeps only last four bits. hope i got my endians straight. this is to avoid prefixing eax /w a byte code above. assumes you've converted ascii characters 0-9 and a-f.

shl edx,ebx ;edx*[(2^n)^(iteration-1)]

add bleh,edx

dec ecx

that should do the trick... my bad. didn't end up using MMX instructions :) reading up on balanced ternary.

here's some algo for division by 3 - I can't assure it's accuracy, I also never tested it thoroughly...

do these steps

```
mov eax, num
```

mov ecx, eax

shr eax, 2

add eax, ecx

shr eax, 1

mov ecx, eax

shr eax, 4

add eax, ecx

mov ecx, eax

shr eax, 8

add eax, ecx

shr eax, 1

make use of a loop here and the stack.
do these steps

- [*]multiply eax by 3, this is shr by 1 and add the original value of eax (eax = eax >> 1 + eax) or (eax = eax * 2 + eax)

[*]subtract the number and eax (x = num - eax)

[*]This will be your remainder or simply your LSD of the final answer. HINT: push into the stack, make use of a counter to track the number of items pushed and pop it afterwards (decrementing the counter) then convert it to ascii (ascii character = popped value +30h), and finally place into buffer

Posted on 2003-02-27 01:46:14 by arkane