0

In matlab I want to convert this:

12345.6788993442355456789

into a vector

[1 2 3 4 5 6 7 8 8 9 9 3 4 4 2 3 5 5 4 5 6 7 8 9]

I have found several solutions to convert a integer into a vector using commands like scanf, num2str,... but those don't fit with non-integers, and some solutions have problems with numbers with a large number of decimal places...

That kind of conversion is needed because I want to see and use all of the digits of the number.

Amro
  • 123,847
  • 25
  • 243
  • 454
Vi_gg_Vi
  • 33
  • 2
  • 5
  • I would treat the number as a string, delete all the `.`s, and then use the code you say works. – Blender Dec 02 '11 at 17:53
  • @Virginia: If you mean that you need to use all digits in a calculation, then don't worry, Matlab will use them even though they won't be displayed by default (though `format long` changes this). – Jonas Dec 02 '11 at 18:30
  • 1
    @Jonas: No, there's too many digits in her example number to "fit" in a `double`; some are lost to roundoff as soon as it's converted. – Andrew Janke Dec 02 '11 at 19:39
  • @AndrewJanke: You're right. That's indeed too many digits. +1 for your solution, btw. – Jonas Dec 02 '11 at 19:50

3 Answers3

3

What input source are you getting those numbers from? And are all those digits significant? Your example numbers are already beyond the relative precision of the double numeric type. The eps function will tell you how much roundoff you're getting.

>> sprintf('%.20f', 12345.6788993442355456789)
ans =
12345.67889934423500000000
>> eps(12345.6788993442355456789)
ans =
    1.818989403545857e-012
>> sprintf('%.20f', 23432.23432345678911111111111100998)
ans =
23432.23432345678900000000
>> eps(23432.23432345678911111111111100998)
ans =
    3.637978807091713e-012

When you type a number in to Matlab source code, it's treated as a literal of type double. So many of those digits are lost as soon as you enter them. See this question for more discussion: In MATLAB, are variables REALLY double-precision by default?.

If you really want to preserve all those digits, you need to avoid storing them in doubles in the first place. Start off with the full number in a string, and then parse it.

function out = parseLongDecimal(str)
ixDot = find(str == '.');
if isempty(ixDot)
    out.whole = arrayfun(@str2double, str);
    out.fraction = [];
else
    out.whole = arrayfun(@str2double, str(1:ixDot-1));
    out.fraction = arrayfun(@str2double, str(ixDot+1:end));
end

That will preserve all the digits.

>> xAsStr = '23432.23432345678911111111111100998';  % as a string literal, not numeric
>> parseLongDecimal(xAsStr)
ans = 
       whole: [2 3 4 3 2]
    fraction: [2 3 4 3 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1 1 1 0 0 9 9 8]

Depending on your use case, you could also just throw it in a Java BigDecimal object and work with it there.

>> jx = java.math.BigDecimal(xAsStr)
jx =
23432.23432345678911111111111100998
Community
  • 1
  • 1
Andrew Janke
  • 23,508
  • 5
  • 56
  • 85
  • The numbers are from a previous computation (which gives me very similar numbers, so i need to focus on the digits on low decimal positions). Thank you for your answer – Vi_gg_Vi Dec 03 '11 at 08:50
  • Is that previous computation being done with `double` values? If so, the digits beyond about 12 past the decimal point are already bogus, due to precision issues, and there's no point trying to preserve them. Or is it using some higher precision type and returning them as strings or something? – Andrew Janke Dec 04 '11 at 05:05
  • It returns double values. How can i use higher precision type? – Vi_gg_Vi Dec 04 '11 at 14:31
  • I'm kind confused. Why if I multiply a double number, obtained by previous computation, , for 10^5 and so on (doing a kind of shift) I obtain digits different from zeros? – Vi_gg_Vi Dec 04 '11 at 14:35
1

Also using num2str, you can do:

sol=arrayfun(@str2num,(sprintf('%f',23432.23432)),'UniformOutput',0)
horzcat(sol{:})

ans =

     2     3     4     3     2     2     3     4     3

Do you want to keep the information about where is the comma?

Oli
  • 15,935
  • 7
  • 50
  • 66
  • Thank you!!...yes i need also where is the comma. – Vi_gg_Vi Dec 02 '11 at 18:24
  • ...but the problem of num2str is that it can convert just a fixed number of digits, making an example: – Vi_gg_Vi Dec 02 '11 at 18:26
  • if I want the number 23432.23432345678911111111111100998, the function you wrote doesn't work – Vi_gg_Vi Dec 02 '11 at 18:27
  • unfortunately the numbers are stored as double in 64 bits, so there is a maximum precision. I edit it to make it more precise. – Oli Dec 02 '11 at 18:31
  • 1
    I mean: as soon as you write 23432.23432345678911111111111100998, matlab convert it to a number with less precision (i. e. double precision, 64 bits) – Oli Dec 02 '11 at 18:41
0

Not familiar with Matlab syntax but if you

  • convert the number to a string
  • loop through each character and add the digit to the vector if the character is not the decimal point

that would work. There are probably more efficient ways to do this.

John
  • 15,990
  • 10
  • 70
  • 110