Преобразование десятичного числа в вектор

В Matlab я хочу преобразовать это:

12345.6788993442355456789

в вектор

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

Я нашел несколько решений для преобразования целого числа в вектор с помощью таких команд, как scanf, num2str,..., но они не подходят для нецелых чисел, а некоторые решения имеют проблемы с числами с большим количеством знаков после запятой...

Такое преобразование необходимо, потому что я хочу видеть и использовать все цифры числа.


person Vi_gg_Vi    schedule 02.12.2011    source источник
comment
Я бы обрабатывал число как строку, удалял все ., а затем использовал код, который, как вы говорите, работает.   -  person Blender    schedule 02.12.2011
comment
@Virginia: Если вы имеете в виду, что вам нужно использовать все цифры в расчетах, то не беспокойтесь, Matlab будет использовать их, даже если они не будут отображаться по умолчанию (хотя format long меняет это).   -  person Jonas    schedule 02.12.2011
comment
@Jonas: Нет, в ее примере слишком много цифр, чтобы поместиться в double; некоторые теряются из-за округления сразу после преобразования.   -  person Andrew Janke    schedule 02.12.2011
comment
@AndrewJanke: Ты прав. Это действительно слишком много цифр. +1 за ваше решение, кстати.   -  person Jonas    schedule 02.12.2011


Ответы (3)


Из какого источника ввода вы получаете эти цифры? И все ли эти цифры значащие? Числа в ваших примерах уже превышают относительную точность числового типа double. Функция eps сообщит вам, какое округление вы получаете.

>> 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

Когда вы вводите число в исходный код Matlab, оно обрабатывается как литерал типа double. Многие из этих цифр теряются, как только вы их вводите. См. этот вопрос для более подробного обсуждения: В MATLAB переменные ДЕЙСТВИТЕЛЬНО двойная точность по умолчанию?.

Если вы действительно хотите сохранить все эти цифры, вам нужно в первую очередь избегать хранения их в двойных числах. Начните с полного числа в строке, а затем проанализируйте ее.

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

Это сохранит все цифры.

>> 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]

В зависимости от вашего варианта использования вы также можете просто добавить его в объект Java BigDecimal и работать с ним там.

>> jx = java.math.BigDecimal(xAsStr)
jx =
23432.23432345678911111111111100998
person Andrew Janke    schedule 02.12.2011
comment
Числа взяты из предыдущего вычисления (что дает мне очень похожие числа, поэтому мне нужно сосредоточиться на цифрах в младших десятичных позициях). Спасибо за ваш ответ - person Vi_gg_Vi; 03.12.2011
comment
Это предыдущее вычисление выполняется с double значениями? Если это так, то цифры после 12 после запятой уже являются поддельными из-за проблем с точностью, и нет смысла пытаться их сохранить. Или он использует какой-то более точный тип и возвращает их в виде строк или что-то в этом роде? - person Andrew Janke; 04.12.2011
comment
Он возвращает двойные значения. Как я могу использовать тип более высокой точности? - person Vi_gg_Vi; 04.12.2011
comment
Я немного смущен. Почему, если я умножаю двойное число, полученное предыдущим вычислением, на 10 ^ 5 и так далее (делая своего рода сдвиг), я получаю цифры, отличные от нулей? - person Vi_gg_Vi; 04.12.2011

Также с помощью num2str вы можете сделать:

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

ans =

     2     3     4     3     2     2     3     4     3

Вы хотите сохранить информацию о том, где находится запятая?

person Oli    schedule 02.12.2011
comment
Спасибо!!... да, мне тоже нужно, где запятая. - person Vi_gg_Vi; 02.12.2011
comment
... но проблема num2str в том, что он может преобразовывать только фиксированное количество цифр, например: - person Vi_gg_Vi; 02.12.2011
comment
если я хочу номер 23432.234323456789111111111111100998, написанная вами функция не работает - person Vi_gg_Vi; 02.12.2011
comment
к сожалению, числа хранятся как двойные в 64 битах, поэтому существует максимальная точность. Я редактирую его, чтобы сделать его более точным. - person Oli; 02.12.2011
comment
Я имею в виду: как только вы пишете 23432.23432345678911111111111100998, Matlab преобразует его в число с меньшей точностью (т.е. с двойной точностью, 64 бита) - person Oli; 02.12.2011

Не знаком с синтаксисом Matlab, но если вы

  • преобразовать число в строку
  • перебрать каждый символ и добавить цифру к вектору, если символ не является десятичной точкой

это сработает. Вероятно, есть более эффективные способы сделать это.

person John    schedule 02.12.2011
comment
Я пробовал, но преобразование числа в строку работает только для фиксированного количества цифр. - person Vi_gg_Vi; 02.12.2011
comment
Как вы теперь храните длинные десятичные числа? - person John; 02.12.2011