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!

Translated by