Counting the number of digits

Hi,
how can I compute the number of digits A=[12875] how can I get 5 as the number of digits in A?

3 Commenti

Jun Wei Ng
Jun Wei Ng il 22 Set 2017
The number divided by 10 until it lower than 1, each time the number divided by 10 need to count 1 and at the end, you will get the digit as the times.
Fails on negative numbers because they are already lower than 1
How many digits does A have in the code below?
A = Inf;
How many digits does B have?
B = NaN;
How about C?
C = 3+4i;

Accedi per commentare.

 Risposta accettata

bym
bym il 3 Lug 2011
One way:
numel(num2str(A))

10 Commenti

Paulo Silva
Paulo Silva il 3 Lug 2011
I made the stupid mistake of using -'0' when it wasn't needed so I'm voting on your answer and removing mine.
Fails with decimals. Ex: n = 99.3;
Fails with negative numbers too.
FINNSTAR7
FINNSTAR7 il 5 Lug 2018
Modificato: FINNSTAR7 il 5 Lug 2018
Since the above responders were pointing out the places bym's answer doesn't work I thought I could suggest an easy fix that works for all real numbers, negative and non-integer alike. Though bym's answer still works for OP's specific case just fine.
numel(erase(num2str(abs(A)),'.'));
For example, in OP's example inputting A = 12875 will output 5 for the number of digits, as desired. And A = -99.3 will output 3.
If you don't want to include the digits after the decimal anyway then you can always truncate A using fix(); or set the fixed-point to 0 like so:
% truncate method
numel(num2str(abs(fix(A))));
% fixed-point method
numel(num2str(abs(A),'%.0f'));
The problem with num2str() is that unless you specify a format, it is like a %.4f followed by trimming off trailing 0.
FINNSTAR7
FINNSTAR7 il 6 Lug 2018
Yeah I noticed that it basically defaults to %.4g too, and I haven't really found a way around that yet. It makes numbers like 1.0000001 impossible to count as it is now.
Counting the number of digits on floating point numbers becomes an exercise in definitions. For example,
a = 1/10;
Let's see... is that .1 giving one digit for the count, or is it 0.1 giving two digits for the count?
Neither is correct:
>> a = 1/10
a =
0.1
>> fprintf('%.999g\n', a)
0.1000000000000000055511151231257827021181583404541015625
which is 57 characters including the leading '0' and '.', so either 55 or 56 digits...
This Answer Fails on floor(pi*1e25)
numel(char(vpa(floor(pi*1e25))))
S1 = num2str(floor(pi*1e25))
S1 = '3.141592653589793e+25'
numel(S1)
ans = 21
S2 = char(vpa(floor(pi*1e25)))
S2 = '31415926535897934939029504.0'
numel(S2)
ans = 28
S3 = char(vpa(floor(sym(pi)*1e25)))
S3 = '31415926535897932384626433.0'
numel(S3)
ans = 28
Actual answer should be 26

Accedi per commentare.

Più risposte (8)

Oleg Komarov
Oleg Komarov il 3 Lug 2011
To count integer part
ceil(log10(abs(A)))
Edit
floor(log10(abs(A)+1)) + 1

4 Commenti

Fails on [-1,1] and all exact powers of 10.
Jan
Jan il 15 Lug 2011
ceil(log10(abs(A) + 1)) ?
Fails on 0, Jan.
Over integral values:
ceil(log10(max(1,abs(A)+1)))
Over real numbers,
ceil(log10(max(1,abs(A)*(1+eps))))
I think.
DGM
DGM il 28 Gen 2023
Modificato: DGM il 28 Gen 2023
It's also necessary to handle cases where A is integer-class.
For sake of clarifying the limitations and assumptions in each suggested method:
A = [-2456 -1.45 0 0.05 0.16 1.5 10 100 35465].';
y1 = ceil(log10(abs(A))); % fails on 0, subunity fractions, powers of 10
y2 = floor(log10(abs(A)+1)) + 1; % 0 has 1 digit? yes/no?
y3 = ceil(log10(max(1,abs(A)+1))); % 0 has 0 digits, but 0.05 and 0.16 both have 1 digit?
y4 = ceil(log10(max(1,abs(A)*(1+eps)))); % fails on powers of 10
y5 = numdigits(A); % where does this one fail?
table(A,y1,y2,y3,y4,y5)
ans = 9×6 table
A y1 y2 y3 y4 y5 _____ ____ __ __ __ __ -2456 4 4 4 4 4 -1.45 1 1 1 1 1 0 -Inf 1 0 0 0 0.05 -1 1 1 0 0 0.16 0 1 1 0 0 1.5 1 1 1 1 1 10 1 2 2 1 2 100 2 3 3 2 3 35465 5 5 5 5 5
function ndigits = numdigits(x)
% NDIGITS = NUMDIGITS(X)
% A simple convenience tool to count the number of digits in
% the integer part of a number. For complex inputs, the result
% is the number of digits in the integer part of its magnitude.
%
% X is a numeric scalar or array of any class or sign.
%
% Note that the integer 0 is considered to have zero digits.
% Consequently, for numbers on the interval -1<X<1, NDIGITS is 0.
ndigits = ceil(log10(abs(double(fix(x)))+1));
end

Accedi per commentare.

Turner
Turner il 16 Ago 2013
Modificato: Turner il 19 Ago 2013
Will do the trick for all nonzero integers:
fix(abs(log10(abs(A))))+1
For a 10,000 iteration benchmark with some above answers:
Jaymin= 1.423717 seconds; Stephanie= 0.476135 seconds; Mine= 0.000878 seconds
If you don't expect 0s to appear, this is the fastest and most accurate method. Only works for decimals that satisfy -1<A<1.

1 Commento

DGM
DGM il 28 Gen 2023
Modificato: DGM il 28 Gen 2023
This doesn't actually provide meaningful results on the specified interval.
x = (-0.15:0.025:0.15).';
y1 = floor(log10(abs(x)+1))+1; % works for all integers (assumes 0 is 1 digit)
y2 = fix(abs(log10(abs(x))))+1; % works for nonzero integers
table(x,y1,y2)
ans = 13×3 table
x y1 y2 ______ __ ___ -0.15 1 1 -0.125 1 1 -0.1 1 2 -0.075 1 2 -0.05 1 2 -0.025 1 2 0 1 Inf 0.025 1 2 0.05 1 2 0.075 1 2 0.1 1 2 0.125 1 1 0.15 1 1
Consider the case of abs(x) = 0.125. In what interpretation does this value have one digit?
Consider the case of abs(x) = 0.10. The naive interpretation of this value might suggest that it has either 1 or 2 digits (depending if you consider the leading integer 0). In reality, 0.1 is not exactly represented in floating point, so instead it's actually 0.999999999999999916 ... etc, or some similar approximation depending on how it was calculated. In base-2, 0.1 has as many digits as your floating-point approximation allows. If 0.125 has 1 digit, then no consistent interpretation would suggest that 0.10 has 2 digits.
As the utility for the fractional part of the number can now be ignored, the only meaningful difference between the two methods presented is the initial offset of 1 to avoid the singularity in log(x). At that point, the distinction between floor() and fix() can be ignored, since all its inputs will be positive.
Bear in mind that for practical use, we should be considering double(x) or something equivalent, otherwise both methods will fail if x is integer-class.

Accedi per commentare.

Jaymin
Jaymin il 13 Dic 2012
Modificato: Walter Roberson il 30 Mag 2020
Long, but it gets the job done.
numel(num2str(A))-numel(strfind(num2str(A),'-'))-numel(strfind(num2str(A),'.'))
fugue
fugue il 26 Mag 2013
numel(num2str(fix(abs(A))))
ARVIND KUMAR SINGH
ARVIND KUMAR SINGH il 30 Mag 2020

0 voti

no_of_digits = numel(num2str(abs(A)));
Mayur Lad
Mayur Lad il 8 Ott 2020
Modificato: Walter Roberson il 8 Ott 2020
x=input('Enter number: ');
disp(x)
sum= 0;
while x > 0
t = mod(x,10);
sum= sum+1;
x = (x-t)/10;
end
fprintf('no of digit is:\t %d',sum)

3 Commenti

This code will not work for negative values.
For the value 0, this code will indicate that the number of digits is 0, but the number of digits for 0 should be 1.
manindra
manindra il 27 Gen 2023
If number is 0 or negative, the control doesn't even enter into the loop. Thats just a dumb question.
I am not clear as to what you are saying is "dumb" ?

Accedi per commentare.

I am using a simplified version of the below to determine whether I should try to represent a number as x*pi, x*sqrt(2), x*exp(1) or a fraction. In my case I only needed to check if there are more than are 14 digits, so no for-loop needed.
It basically finds the difference between the first and last non-zero number. Sign, decimal point and exponent are not included in the count.
a = [0,12e-17,1,10,21003, round(pi,3)*1e6, round(pi,5), round(pi,10), round(pi,10)*1e-3, round(pi*1e-5,10), pi, pi*1e307, pi*1e-314];
a = [a, -a];
for i=1:length(a)
b=abs(a(i)); % sign is not important for the number of digits, but feel free to add 0>sign(a(i)) to sd
if b < 3e-323 % depending on how precise you want to be
sd = 1; % could be changed to zero depending on your usecase
else
msd=floor(log10(b)); % most significant digit
lsd=-inf;
for dp=msd:-1:-323 % again depending on how precise you want to be, numbers really close to zero gets a little ify
if mod(b,10.^dp)==0
lsd=dp-1; % least significant digit
break
end
end
sd = msd-lsd; % number of digits
end
fprintf('%d significant digits\tin\t%s\n', sd, num2str(a(i), 16))
end
The approach that i followed is in which i used a recursive function to compute the sum of digits of the integer provided such that the sum of A=[12345] is 15.
function x=digit_sum(input)
if input==0
x=0;
else
digit = rem(input,10);
input=(input-digit)/10;
x=digit+digit_sum(input);
end
end
You can see that for getting the 10th of the integer, i just divided the number by 10, and the remainder gave us the last digit, which in turn was added using a recursive function.

1 Commento

Is this what you expected? I added one additional input to your function so it shows you the intermediary steps.
digit_sum(pi, true)
Digit is 3.14159, input is 0
ans = 3.1416
You can see the effect of the additional input on a problem where this function works:
digit_sum(12345, true)
Digit is 5, input is 1234 Digit is 4, input is 123 Digit is 3, input is 12 Digit is 2, input is 1 Digit is 1, input is 0
ans = 15
The following behavior is what I expected for a non-finite input, since you are recursively calling digit_sum with Inf as the input each time. The same holds if you call digit_sum with NaN as input. I'm not showing the intermediate results, as I suspect the displaying of those steps would cause this code to time out in MATLAB Answers.
digit_sum(Inf, false)
Out of memory. The likely cause is an infinite recursion within the program.

Error in solution>digit_sum (line 13)
x=digit+digit_sum(input, displaySteps);
Your code would also fail if input was a complex number.
function x=digit_sum(input, displaySteps)
if input==0
x=0;
else
digit = rem(input,10);
input=(input-digit)/10;
if displaySteps
fprintf("Digit is %g, input is %g\n", digit, input);
end
x=digit+digit_sum(input, displaySteps);
end
end

Accedi per commentare.

Categorie

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by