File Exchange

## Round with significant digits

version 1.6.0.0 (3.05 KB) by
Rounds towards the nearest number with N significant digits.

Updated 03 Apr 2015

Editor's Note: This file was selected as MATLAB Central Pick of the Week

This little function rounds a number (or the elements of a vector ot matrix) towards the nearest number with N significant digits.
Examples:
roundsd(0.012345,3) returns 0.0123
roundsd(12345,2) returns 12000
roundsd(12.345,4,'ceil') returns 12.35
This is a useful complement to Matlab's ROUND, ROUND10 and ROUNDN (Mapping toolbox), especially when dealing with data with a large variety of order of magnitudes.

I was about to upload this file when I found "sd_round.m" by Edward Zechmann (see aknowledgment), which has similar feature (and more). But, because my script is very different in coding (much much shorter), I decided to share it anyway.

### Cite As

François Beauducel (2021). Round with significant digits (https://www.mathworks.com/matlabcentral/fileexchange/26212-round-with-significant-digits), MATLAB Central File Exchange. Retrieved .

Martin Stolpe

Karol Postawa

Osman Malik

Nikos K

Peter Sneftrup

Thanks for the excellent little utility. I like the different rounding methods that are supported.

The error Colin Morris identified is in line 74:

if ~ischar(method) || ~ismember(opt,method)

The problem comes from the "ismember(opt, method)" requirement. From the R2011b
documentation, "ismember" returns a logical array the same size as the first argument.

Replacing the line with this:

if ~ischar(method) || ~ismember(method, opt)

fixes the problem.

Nelson

How is this function different from the Matlab built-in funciton chop?

I noticed chop doesn't have a doc page, so it's impossible to find with docsearch.

Colin Morris

Running on 2011a. I believe if found an error between lines 73-76. When explicitly stating the method ( i.e. 'fix',or 'ceil'), I receive the runtime error :

??? Operands to the || and && operators must be convertible to logical scalar values.

Error in ==> roundsd at 74
if ~ischar(method) || ~ismember(opt,method)

commenting the else statement between lines 73-76 solves the issue for me.

-C

Chris Patterson

Franck Dernoncourt

Yuri K

Great function. I should find it earlier.

Will, it's a precision problem of floating point arithmetic. Try:
3.55/0.1-35.5
ans =
-7.105427357601e-15
This little number trigger the balance. I think it's hard to overcome.

Will

Does not work in all cases. Try rounding 3.55 to 1 decimal place and you get 3.5 instead of 3.6

Kamran Syed

veru good

Tobias Lamour

a very useful extension to the usual round functions.

one small speed improvement can be achieved. Using find is very slow. one can use logical indexing just like this:
y(x==0) = 0;
it does the same job while much faster with lager arrays.
Thanks,
Tobi

Walter de Vries

Very nice simple and compact code.
Should be build into next Matlab versions.

Milan

Nik F

K E

Brent Boehlert

Much appreciated -- thanks.

K E

So useful that it should be built in to the Matlab round function, as it is in other languages

Sunday

Forrest Brett

Oleg Komarov

I think your submission deserves a much better overall rating.

François Beauducel

Thanks Oleg.

1) you effectively need the "find" in Matlab versions < 7... and also single pipe for the OR test.
2) like you I have hesitated between "switch" and "feval". But the feval code is much shorter...

François.

Oleg Komarov

I would mention in the see also line the other rounding functions you use.

I never used matlab < 7 so I don't know if this applies:
1) no need to use find: y(find(x==0)) = 0;
2) I would use switch case instead of feval.

Oleg

François Beauducel

Thanks Daniel for your time. I submitted an updated version that corrects the zero-value behaviour, and I added some options for the rounding method.
About the mlint messages, I kept my original syntax which is voluntarily backward compatible (with Matlab versions < 7).

Daniel Armyr

I also noticed some mlint-messages that I fixed. The core of the code now looks like this:

if ~isnumeric(n) || numel(n) ~= 1 || n < 0 || mod(n,1) ~= 0
error('N argument must be a scalar positive integer.')
end

valuesZero = (x==0);
og = 10.^(floor(log10(abs(x)) - n + 1));
y = round(x./og).*og;
y(valuesZero) = 0;

Daniel Armyr

I just wrote one of these and was anout to upload it. But since you had allready done it, there is no point. This file would get a very high mark by me for several reasons:
1) Simple function, no bloated features
2) Error checking.
3) Well formated documentation.

Unfortunately, your script doesn't handle 0. That pulls down the mark significantly.

##### MATLAB Release Compatibility
Created with R13
Compatible with any release
##### Platform Compatibility
Windows macOS Linux