2

I have the following vector

vec = [ 255     0   255     0   255     0   255     0   255     0   255     0   255     0   255     0]

vec 1x16 double

and using the following command

polyval(vec', 256);

I get

ans = 3.3896e+038

but when I try to get back my original vector

vec2 = decimal2base(ans, 256)

I get

vec2 = 255     0   255     0   255     1     0     0     0     0     0     0     0     0     0     0

and this is clearly not my original vector.

Whats more if again I run polyval in this vector

polyval(vec2', 256); 

I get

ans=

  3.3896e+038

I am not entirely sure what sort of mistake I am making as I know that my conversion functions are ok, so it must be a number precision thing.

chappjc
  • 30,359
  • 6
  • 75
  • 132
ealiaj
  • 1,525
  • 1
  • 15
  • 25

2 Answers2

4

Ah, large numbers. The value 3.3896e+038 is higher than the maximum integer that can be represented by a double without loss of accuracy.

That maximum number is 2^53 or

>> flintmax('double')
ans =
   9.0072e+15

So you are losing accuracy and you cannot reverse the computation.


Doing the computations with uint64 values only:

>> pows = uint64(fliplr(0:numel(vec)-1));
>> sum(uint64(vec).*(uint64(256).^pows),'native')
ans =
 18446744073709551615

That's about 1.84e+19. Just a little different from what you get if you use doubles. But wait... that number looks familiar:

>> intmax('uint64')
ans =
 18446744073709551615

So, you've maxed out unsigned 64-bit integers too:

>> uint64(256).^pows
ans =
  Columns 1 through 5
 18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615 18446744073709551615
  Columns 6 through 10
 18446744073709551615 18446744073709551615 18446744073709551615    72057594037927936      281474976710656
  Columns 11 through 15
        1099511627776           4294967296             16777216                65536                  256
  Column 16

When you get above 255^8 or so, you're passing intmax('uint64') and you can't manage numbers this large, at least not with MATLAB's built-in data types.

chappjc
  • 30,359
  • 6
  • 75
  • 132
  • isn't there a way to get past this? – ealiaj Apr 24 '14 at 18:21
  • @green_leaf As far as I can tell, `polyval(vec', 256)` is very wrong. Try it manually, see updated answer. – chappjc Apr 24 '14 at 18:30
  • @green_leaf I think you can't even do it manually with 64-bit integers, see another update. – chappjc Apr 24 '14 at 18:41
  • granted, but what if i tried to do this base256 to decimal and opposite conversion using symbolic math or variable precision numbers, would I have a chance then @chappjc – ealiaj Apr 24 '14 at 18:48
  • @green_leaf Yeah, I suppose so. [This example](http://www.mathworks.com/help/symbolic/examples/variable-precision-arithmetic.html) shows computations with up to 780 decimal places of pi and 200 digits of 70!. If you have the toolbox (I don't) I suppose you could do it. Interesting problem you've got! – chappjc Apr 24 '14 at 18:51
  • Yeah @chappjc usually all my questions in SO look kind of weird, mostly because I have weird ideas that I want to test out. Just to make sure though, how would I use this method in my case, because in order to convert a vector to decimal or the opposite i need to use a for loop (at least if I use the functions that I created). Also if you don't have the toolbox I recommend the awesome VPA toolbox by John D'Errico that you can easily find in File Exchange. – ealiaj Apr 24 '14 at 19:08
  • @green_leaf With the `.^` and `.*` operators, no loops is needed. See the two commands starting with `pows = ` in the answer. Is that what you mean? Thanks for the tip about the VPA toolbox. – chappjc Apr 24 '14 at 19:15
  • So to sum it up, if one needs to work with really big numbers (eg >256^8) then he should try either _symbolic computing_ either _Variable Precision Arithmetic_. Thanks @chappjc for clearing that up for me. – ealiaj Apr 24 '14 at 19:45
0

see if this returns '1':

polyval(vec(6:end),256)==polyval(vec2(6:end),256);

If so, then it's just a property of '255+1' for that special 'vec'.

oligilo
  • 161
  • 8