# Return largest number of decimal places in a vector of numbers

11 ビュー (過去 30 日間)
James Daniel 2023 年 9 月 19 日
コメント済み: James Daniel 2023 年 9 月 20 日
I'm trying to return the largest number of decimals from a vector of numbers. So say if I had x=[0.1,0.12,0.123,0.1234] I'd want an output of 4.
function [y] = maxdecimals(x)
for a = 1:length(x)
b(1,a) = strlength(num2str(abs(x(1,a))-floor(abs(x(1,a)))))-2;
% Creates vector with number of decimals
end
y = max(b);
% Finds maximum decimal number within vector
end
I'm getting a problem where if the number of decimal places is greater than 5, it doesn't seem to work. E.g. for x=[0.123456789,0.1,0.12,0.123] I get an output of 5, even though I should be getting 9.
For example, I input 0.123456789 and I get 5
strlength(num2str(abs(0.123456789)-floor(abs(0.123456789))))-2
ans =
5
Is there something about num2str that doesn't work for a certain length of numbers or is it something to do with the format limiting the number of decimal places?
>> num2str(abs(0.123456789)-floor(abs(0.123456789)))
ans =
'0.12346'

サインインしてコメントする。

### 回答 (4 件)

Bruno Luong 2023 年 9 月 20 日

Good point from @Image Analyst, but I would add a comment:
All finite floating numbers when translated to decimal MUST eventually finish by 0 sequence.
x = [0.123456789,0.1,0.12,0.123];
fprintf('%.100f\n', x)
0.1234567889999999973360544913703051861375570297241210937500000000000000000000000000000000000000000000 0.1000000000000000055511151231257827021181583404541015625000000000000000000000000000000000000000000000 0.1199999999999999955591079014993738383054733276367187500000000000000000000000000000000000000000000000 0.1229999999999999982236431605997495353221893310546875000000000000000000000000000000000000000000000000
Why? because they are sum of power 2, and each power 2 can be written exactly in 10 base with finite number of digits, since 2 divides 10.
So actually the answer [9 1 2 3] for the above x is wrong, strictly speaking.
x = [0.123456789,0.1,0.12,0.123];
s = arrayfun(@(x)sprintf('%.150f', x), x, 'unif', 0);
truedigitlength = cellfun(@(s) find(s~='0',1,'last')-2, s)
truedigitlength = 1×4
56 55 53 52
To get the wanted [9 1 2 3] output, one needs to specify the length for truncation and rounding in 10 base, e.g. around 15, 16 (-log10(eps)), which is kind of arbitrary definition. and likely to fail for numbers "small" x (with log10(x) << -1).
##### 2 件のコメントなしを表示なしを非表示
Image Analyst 2023 年 9 月 20 日
@Bruno Luong thanks for clarifying and expanding. I think this is the best and most accurate answer posted so far.
James Daniel 2023 年 9 月 20 日
@Bruno Luong I agree with @Image Analyst this is great clarification, thank you for your help

サインインしてコメントする。

Stephen23 2023 年 9 月 19 日

x = [0.123456789,0.1,0.12,0.123];
n = strlength(compose("%.15g",rem(abs(x),1)))-2
n = 1×4
9 1 2 3
##### 0 件のコメント-2 件の古いコメントを表示-2 件の古いコメントを非表示

サインインしてコメントする。

Bruno Luong 2023 年 9 月 19 日

Check out the second input of num2str in the doc (in general always read the doc throughly most of the time the answer is right there).
##### 0 件のコメント-2 件の古いコメントを表示-2 件の古いコメントを非表示

サインインしてコメントする。

Image Analyst 2023 年 9 月 19 日
All double numbers have the same number of decimal points, unless they're rounded, because they're all 64 bit numbers. Watch:
x = [0.123456789,0.1,0.12,0.123];
fprintf('%.50f\n', x)
0.12345678899999999733605449137030518613755702972412 0.10000000000000000555111512312578270211815834045410 0.11999999999999999555910790149937383830547332763672 0.12299999999999999822364316059974953532218933105469

サインインしてコメントする。

### カテゴリ

Help Center および File ExchangeImage Arithmetic についてさらに検索

R2022b

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!