PDA

Click to See Complete Forum and Search --> : Convert Binary to decimal?? How?


Sophtware
Dec 15th, 2000, 09:09 PM
Can some one explain this process?

Guv
Dec 15th, 2000, 10:46 PM
I am assuming you want to know the process or some algorithms instead of code. First what is a binary number? Easiest to show by example.
1011.101 = 8 + 2 + 1 + 1/2 + 1/8
Zero bits merely take up space. One bits to the left of the binary point stand for powers of 2 (From right to left: 1, 2, 4, 8, 16, et cetera). One bits to the right of the binary point stand for negative powers of two (From left to right: 1/2, 1/4, 1/8, 1/16, et cetera).

If you can do binary arithmetic, convert fractional binary by multiplying by ten (1010 in binary) and using the integer part of the product. Example follows.

.101 = .625
If you multiply .101 by 1010, you get 110.010
110 = 6: 6 is first digit to right of decimal point.
.01 * 1010 = 10.10:
10 = 2: 2 is next digit.
.10 * 1010 = 101.00
101 = 5, 5 is next digit.
Stop now, because the binary value is zero.

To convert integer binary, divide by 10 and use remainders as decimal digits. Example follows.

100101001 = 297
divide 100101001 by 1010, getting 11101 with a remainder of 111
111 is 7: 7 is first digit to the left of the decimal point.
Divide 11101 by 1010, getting 10 with a remainder of 1001
1001 is 9: Next digit is 9
Divide 10 by 1010, getting 0 with a remainder of 10
10 is 2: Next digit is 2.

Use loops to code the above.

I hope the above gives you the general idea. Similar algorithms can be used to convert between other radix notations. For exampel: If converting from Radix 12 to hexidecimal (Radix 16), you have to be able to do radix 12 arithmetic. Multiply by 16 to convert fractions; Divide by 16 to convert integers.

Sophtware
Dec 15th, 2000, 11:57 PM
I appreciate you explaining it.

Sam Finch
Dec 16th, 2000, 06:16 AM
I did this a couple of days ago, Guv explained it pretty well so there's no need to explain it again, here's some free code tho


//Number to String Function
//Fills an Expression Block with a New DC containing a number
void NumberToString(int Number, char* NumberString)
{
//Number String is a will contain the Number as a string
NumberString = new char[12];

__asm //this block of assembly code converts the Integer into a string
{ //The same as VBs CString()

push eax //preserve the registers we use
push ebx
push ecx
push edx


mov eax, Number //eax holds the number
mov ebx, NumberString //ebx holds the place in the string we're writing to

push 32 //push 32 as a double word, this will be interpreted as
//2 seperate words a 0 and a 32 the 32 is a space
//the 0 is our signal we have reached the end
//(we have to put the space there as it was cutting bits off the numbers

mov ecx, 10 //set ecx to 10 as we can't divide by immediate values


cmp eax, 0 //if the number is less than 0 we negate it and add a
jge LoopStrt // - sign to the start of the string
neg eax
mov [ebx], 45
inc ebx

LoopStrt:

mov edx, 0 //loop around dividing by 10
div ecx //div with a 32bit operand divides edx:eax by the operand
//leaving the result in eax and the remainder in edx

add edx, 48 //add 48 to the remainder to turn it into the ascii value of the number
//eg 5 --> 53 chr$(53) = '5'

push dx //Push the character to the stack
//(NB we push a word for every character as there is
//no single byte push instruction

cmp eax, 0 //if eax is nonzero we have more characters to add
jne LoopStrt

LoopStrt2:

pop cx //loop around poping a word off the stack
mov [ebx], cl //and adding the LO byte to the string
inc ebx

cmp cx,0 //after we've poped the zero we pushed at the top
jne LoopStrt2 //we know we've finished (the zero is still written
//as it's a null terminated string.

pop edx //restore the registers as they were
pop ecx
pop ebx
pop eax
}

}



it's in C++ with inline asm, I hope that's all right. It basicly used Guv's algorithm, and pushes letters to the stack as it gets them, then pops them off into a string. It uses the fact that if you have a single digit number you can add 48 to get the ascii value (48 = '0', 49 = '1' ..)



[Edited by Sam Finch on 12-16-2000 at 07:32 AM]

Sophtware
Dec 16th, 2000, 11:24 AM
Thanks for the free code .. now i have something to work with.

One more Q

I know this is a little off post but...
can i use this code in most asm compilers?

Is the syntax universal? so i wont have too change the code around (not that i know how or anything ;) )


Thanks again.

Sam Finch
Dec 16th, 2000, 11:53 AM
in most compilers it will work, but you do need to change it slightly, your best bet is to use it as a procedure, passing parameters in global variables, you'd need something like this (the comments are C++ comments, I've taken them out and put some ASM Coments in




[declare universal variables to pass the parameters in
dd Number ?
db NumberString ?,?,?,?,?,?,?,?,?,?,?,?




PROC NumberToString

push eax ;preserve the registers we use
push ebx
push ecx
push edx


mov eax, Number ;eax holds the number

;I've changed the next line
lea ebx, NumberString ;ebx holds the place in the string we're writing to

push 32 ;push 32 as a double word, this will be interpreted as
;2 seperate words a 0 and a 32 the 32 is a space
;the 0 is our signal we have reached the end
;(we have to put the space there as it was cutting bits off the numbers

mov ecx, 10 ;set ecx to 10 as we can't divide by immediate values


cmp eax, 0 ;if the number is less than 0 we negate it and add a
jge LoopStrt ; - sign to the start of the string
neg eax
mov [ebx], 45
inc ebx

LoopStrt:

mov edx, 0 ;loop around dividing by 10
div ecx ;div with a 32bit operand divides edx:eax by the operand
;leaving the result in eax and the remainder in edx

add edx, 48 ;add 48 to the remainder to turn it into the ascii value of the number
;eg 5 --> 53 chr$(53) = '5'

push dx ;Push the character to the stack
;(NB we push a word for every character as there is
;no single byte push instruction

cmp eax, 0 ;if eax is nonzero we have more characters to add
jne LoopStrt

LoopStrt2:

pop cx ;loop around poping a word off the stack
mov [ebx], cl ;and adding the LO byte to the string
inc ebx

cmp cx,0 ;after we've poped the zero we pushed at the top
jne LoopStrt2 ;we know we've finished (the zero is still written
;as it's a null terminated string.

pop edx ;restore the registers as they were
pop ecx
pop ebx
pop eax

ret ;return from function

ENDP NumberToString


then if you want the contents of eax to become a string do this

mov Number, eax
call NumberToString


and NumberString will be filled up with a string representing that number.