5

I created the following simple matlab functions to convert a number from an arbitrary base to decimal and back

this is the first one

function decNum = base2decimal(vec, base)

decNum = vec(1);
for d = 1:1:length(vec)-1
    decNum = decNum*base + vec(d+1);     
end 

and here is the other one

function baseNum = decimal2base(num, base, Vlen)
ii = 1;
if num == 0
    baseNum = 0;
end
while num ~= 0 
    baseNum(ii) = mod(num, base);
    num = floor(num./base);
    ii = ii+1;
end
baseNum = fliplr(baseNum);

if Vlen>(length(baseNum))
    baseNum = [zeros(1,(Vlen)-(length(baseNum))) baseNum ];
end

Due to the fact that there are limitations to how big a number can be these functions can't successfully convert vary big vectors, but while testing them I noticed the following bug

Let's use the following testing function

num = 201;

pCount = 7
x=base2decimal(repmat(num-1, 1, pCount), num)
repmat(num-1, 1, pCount)
y=decimal2base(x, num, 1)
isequal(repmat(num-1, 1, pCount),y) 

A supposed vector with seven (7) digits in base201 works fine, but the same vector with base200 does not return the expected result even though it is smaller and theoretically should be converted successfully.

11
  • You have two functions that some how don't work in combination. All in all this is quite a bit of code. Please try to test them individually to find the source of the problem and zoom in on the problem area in the code. Once you trim it down to 3 lines or so, we can easily help you and probably you can already solve the problem yourself. Commented Jul 3, 2014 at 12:23
  • You could try to go over to cells. seems to be easier. An alternative is to have a maximal permitted number and then fill up with zeros. There is a reason that this is how things usually is done. Commented Jul 3, 2014 at 12:30
  • @DennisJaheruddin it is a bit hard debugging this sort of code that way as it deals with very big numbers and as I stated it works fine except for some 'weird' cases as the one I mentioned, so I was mostly hoping someone else had encountered this behavior, as my conversion functions are directly taken from what we know from theory about number bases (unless I have done some obvious mistake). Commented Jul 3, 2014 at 12:42
  • @patrik I am not sure i understood your suggestion correctly, the number [200] should be within bounds as the one bigger than it [201] seems to be ok. Commented Jul 3, 2014 at 12:44
  • 2
    with base 200 and the vector [199,199,199,199,199,199,199] the base2decimal function on the last step of the loop calculates 63999999999999.0*200+199 which I assume due to floating point limitations equals 12800000000000000.0 instead of 12799999999999999.0, but this is not expected to be a floating point error as eps(12799999999999999.0) = 0.5 so it seems this it can hold this accuracy... although as eps(1.28e16)=2 the calculated number is the last integer-valued double with accuracy less than 1. Commented Jul 3, 2014 at 12:50

2 Answers 2

1

(One preliminary comment: calling base2decimal won't result in a decimal number but rather in a number :-D)

This is due floating-point limited precision (in our case, double). To test it, just type at the MATLAB Command Window:

>> 200^7 - 1 == 200^7

ans = 

     1

>> mod(200^7 - 1, 200)

ans =

     0

which means that the value of your number in base 200 (which is precisely 2007−1) is represented exactly as 2007, and the "true" value of representation is 2007.

On the other hand:

>> 201^7 - 1 == 201^7

ans =

 1

so still the two numbers are represented the same, but

>> mod(201^7 - 1, 201)

ans =

   200

which means that the two values share the "true" representation of 2017−1, which, by accident, is the value that you expected.

TL;DR

When stored in a double, 2007−1 is inaccurately represented as 2007, while 2017−1 is accurately represented.

"Bigger numbers are less accurately represented than smaller numbers" is a misconception: if it was true, there would be no big numbers that could be exactly represented.

0

Judging from your own observations:

  1. The code works fine in most cases
  2. The code can give small errors for large numbers

The suspect is apparent:

Rounding issues seem to give you headaces here. This is also illustrated by @RTL in the comments.


The first question should now be: 1. Do you need perfect accuracy for such large numbers? Or is it ok if it is off by a relatively small amount sometimes?

If that is answered with a yes, I would recommend you to try a different storage format. The simple solution would be to use big integers:

uint64

The alternative would be to make your own storage format. This is required if you need even bigger numbers. I think you can cover a huge range with a cell array and some tricks, but of course it is going to be hard to combine those numbers afterwards without losing the accuracy that you worked so hard for.

3
  • I do not like it. You need to let every "number" have the same number of digits like v=[xxx,xxx,xxx,...], eg a number 211 for base 105 should be a vector v=[002,001]. This also allows decimals. Commented Jul 3, 2014 at 13:11
  • @patrik Not sure about the comment, but I also found a pair of functions: bigbase2dec and dec2bigbase. These are likely bugfree but of course they will still have limitations. See near the bottom of this page. Commented Jul 3, 2014 at 13:18
  • This is certainly nice, but what I mean is that the same as each decimal digit is one element of the number, the base larger than decimals still need to consist of one element. Since matlab still uses base 10 you will need to come up with something else. Eg a vector of elements. For example 215 in base 100 is [02,15]. Commented Jul 3, 2014 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.