# Numeric Base Conversion Problem

## Recommended Posts

Hi,

I have a problem converting numbers from base 10 to base 16.

I created an algorithm (shown below) that converts base 10 numbers to any base numbers, but seems

like it's not accurate. I checked at the forum and found more than an year old topic

with similar algorithm that makes the same mistake converting numbers.

Here is the topic : Number base conversion UDF

I can't explain what causes the problem so I will give an example:

I try to convert the number 9999999999999999 from base 10 to 16 so I use my algorithm and get the answer 2386F26FC1

(the answer should be 2386F26FC10000 which I will fix later) I convert 2386F26FC10000 back to base 10 and get

10000000000000000 which is not the number I converted in the first place. So I convert 9999999999999999 from base

10 to base 16 using windows calculator and get the answer 2386F26FC0FFFF which converted back to base 10 gives

9999999999999999 equal to the number that I converted in the first place.

So I decided to see how my algorithm works and put an array to collect data during the conversion. The array values are:

Now I can see why the algorithm doesn't work, but I don't understand how to fix it.

My question is: How can I detect when this inaccuracy occurs so I can fix it?

```Func ConvertIntToBase(\$num,\$base)
If \$num == 0 Then Return 0
Local \$ret = ""
Local \$div = FindMAxPowerOfBase(\$num,\$base)
Local \$dig, \$sub
Local \$arr[100][5], \$i = 0

Do
\$arr[\$i][0] = \$num
\$arr[\$i][2] = \$div

\$dig = Int(\$num/\$div)
\$sub = \$dig*\$div
\$num-=\$sub
\$div/=\$base
\$ret &= NumToLetter(\$dig)

\$arr[\$i][1] = \$sub
\$arr[\$i][3] = NumToLetter(\$dig)
\$i+=1
Until \$num == 0
_ArrayDisplay(\$arr)
Return \$ret
EndFunc

Func FindMAxPowerOfBase(\$num,\$base)
Local \$n = 1
Do
\$n *= \$base
Until \$n > \$num
\$n /=\$base
Return \$n
EndFunc```

EDIT: The algorithm works like this:

1. Determines the power N of the base Base at which Base^N > Number you are trying to convert.

2. Forms a divisor Div=Base^(N-1)

3. Divedes the Number/Div and retrieves the digits of number converted to base Base

Each time a digit Dig is retrieved Dig*Div is sustracted from the Number and Div is devided by Base

Example: I will convert the number 35 from base 10 to base 16 using this algorithm

1. Determine the power N

16^1 = 16 > 35 -> no

16^2 = 266 > 35 -> yes

so the power is 1

2. The initial Divisor is 16

3. Finding the digits of 35 converted to base 16.

Dig = Int(35/16) = 2

Reminder = 35-2*16=35-32=3

NumberBase16 = 2

Div = 16/16 = 1

Dig = Int(3/1) = 3

Reminder = 3-3*16^0 = 0 (final loop)

NumberBase16 = 23

Edited by eXirrah

##### Share on other sites

Couldn't you just use Hex() to convert from base 10 to 16? Maybe I'm not following correctly...

For those who are asking questions, look in the help file first. I'm tired of people asking stupid questions about how to do things when 10 seconds in the help file could solve their problem.[quote name='JRowe' date='24 January 2010 - 05:58 PM' timestamp='1264381100' post='766337'][quote name='beerman' date='24 January 2010 - 03:28 PM' timestamp='1264372082' post='766300']They already have a punishment system for abuse.[/quote]... and his his name is Valik.[/quote]www.minikori.com

##### Share on other sites

I'm thinking it's caused by a precision error with your calculated divisor.

Is the data type you used for the divisor enough to store that large a number?

##### Share on other sites

What you experience is the limited precision of floating point. It can get fairly complex to monitor precision and recover from precision loss along a significant FP calculation.

Do you really need to manage numbers that large? If so, search the forum for an UDF for Big Numbers, an arbitrary precision artihmetic set of functions. It's slower than native FP of course but it should work for you.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

##### Share on other sites

Couldn't you just use Hex() to convert from base 10 to 16? Maybe I'm not following correctly...

I use this function to convert to other bases than 16 as well. It's just that the problem occurs when I convert to base 16 (I thought).

I'm thinking it's caused by a precision error with your calculated divisor.

Is the data type you used for the divisor enough to store that large a number?

Yes, the variable can store the divisor. The problem is in the precision when it devides by it.

What you experience is the limited precision of floating point. It can get fairly complex to monitor precision and recover from precision loss along a significant FP calculation.

Do you really need to manage numbers that large? If so, search the forum for an UDF for Big Numbers, an arbitrary precision artihmetic set of functions. It's slower than native FP of course but it should work for you.

You are right, man! I found a BigNum UDF here on the forum and with it the algorithm works fine. Thanks.

I will thank the creator of the UDF as well on the UDF topic page.

Ah.. I can't give reputation points, probably cause I'm new to the forum. Sorry, but all I can do is

just thank you.

Edited by eXirrah

## Create an account

Register a new account