Define function for rounding to precision

2 次查看(过去 30 天)
Hi,
Rather than use the fix, floor, ciel functions, I’m trying to create a function to round a number up to a prescribed decimal place.
Eg.
Function roundup_value = ROUNDUP(value, decimalPlaces)
Any help would be greatly appreciated.

回答(1 个)

Adam
Adam 2019-8-14
Usual scenario would be to multiply by 10^decimalPlaces, ceil and then divide by 10^decimalPlaces I would imagine.
e.g.
ceil( 1.23456789 * 10^4 ) / 10^4
You could probably use
doc round
with the second argument too, although if you want to enforce always rounding up it likely isn't worth it. I don't know why equivalent versions of ceil and floor don't exist. It was added relatively recently to round rather than in the original implementation, but I would have thought all that family of functions should have been updated the same way.
  1 个评论
John D'Errico
John D'Errico 2019-8-14
编辑:John D'Errico 2019-8-14
Adam makes a good point, in that if round was extended as it was, then why did ceil and floor not get the same treatment? My guess is for the same reason I never thought to look to see if ceil and floor had the new capability. It is just something I've never had the slightest desire to do. Yes, I'll suppose a round to n digits has been at times useful, though I think it has been more when I answer a question about exactly that. Personally, I tend not to use it at all.
So why not? Why do I rarely ever use the capability to round a number to tenths, hundreths, etc? I tend not to do so, because I know that it is a fallacy in double precision floating point arithmetic to trust that a number is exactly rounded/truncated/ceiled to the nearest 0.1, or almost any fraction of an integer. (I do trust that Adam knows all this.)
format long g
X = rand(1,3)
X =
0.925425280986515 0.00558112226984153 0.186388406230158
Y = floor(X*10)/10
Y =
0.9 0 0.1
But are they exactly 0.9. 0, and 0.1? Only in the second case are they so.
sprintf('%0.55f',Y(1))
ans =
'0.9000000000000000222044604925031308084726333618164062500'
sprintf('%0.55f',Y(2))
ans =
'0.0000000000000000000000000000000000000000000000000000000'
sprintf('%0.55f',Y(3))
ans =
'0.1000000000000000055511151231257827021181583404541015625'
You can round/ceil/floor a number exactly to a fraction that is a pure power of 2 though. So to round/ceil/floor to the nearest multiple of 1/8, thus a pure power of 2, even though it is a negative power of 2?
Y8 = floor(X*8)/8
Y8 =
0.875 0 0.125
sprintf('%0.55f',Y8(1))
ans =
'0.8750000000000000000000000000000000000000000000000000000'
We can see it is stored as exactly 0.875 too, using my num2bin utility.
num2bin(Y8(1))
ans =
struct with fields:
Class: 'double'
Sign: 1
Exponent: -1
Mantissa: '11100000000000000000000000000000000000000000000000000'
BinaryExpansion: [-1 -2 -3]
BiSci: '1.1100000000000000000000000000000000000000000000000000 B-1'
BiCimal: '0.11100000000000000000000000000000000000000000000000000'
So Y8(1) is EXACTLY represented internally as 1/2 + 1/4 + 1/8 = 0.875.
So, while I accept that floor and ceil arguably should have been extended as was done to round, most of the time, you really are not getting what you asked for anyway.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Programming 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by