Reputation: 75
I have a rather unorthodox homework assignment where I am to write a simple function where a double
value is rounded to an integer with using only a while
loop.
The main goal is to write something similar to the round function.
I made some progress where I should add or subtract a very small double
value and I would eventually hit a number that will become an integer:
while(~isinteger(inumberup))
inumberup=inumberup+realmin('double');
end
However, this results in a never-ending loop. Is there a way to accomplish this task?
I'm not allowed to use round
, ceil
, floor
, for
, rem
or mod
for this question.
Upvotes: 0
Views: 478
Reputation: 104545
Assumption: if
statements and the abs
function are allowed as the list of forbidden functions does not include this.
Here's one solution. What you can do is keep subtracting the input value by 1 until you get to a point where it becomes less than 1. The number produced after this point is the fractional component of the number (i.e. if our number was 3.4, the fractional component is 0.4). You would then check to see if the fractional component, which we will call f
, is less than 0.5. If it is, that means you need to round down and so you would subtract the input number with f
. If the number is larger than 0.5 or equal to 0.5, you would add the input number by (1 - f)
in order to go up to the next highest number. However, this only handles the case for positive values. For negative values, round
in MATLAB rounds towards negative infinity, so what we ought to do is take the absolute value of the input number and do this subtraction to find the fractional part.
Once we do this, we then check to see what the fractional part is equal to, and then depending on the sign of the number, we either add or subtract accordingly. If the fractional part is less than 0.5 and if the number is positive, we need to subtract by f
else we need to add by f
. If the fractional part is greater than or equal to 0.5, if the number is positive we need to add by (1 - f)
, else we subtract by (1 - f)
Therefore, assuming that num
is the input number of interest, you would do:
function out = round_hack(num)
%// Repeatedly subtract until we get a value that less than 1
%// i.e. the fractional part
%// Also make sure to take the absolute value
f = abs(num);
while f > 1
f = f - 1;
end
%// Case where we need to round down
if f < 0.5
if num > 0
out = num - f;
else
out = num + f;
end
%// Case where we need to round up
else
if num > 0
out = num + (1 - f);
else
out = num - (1 - f);
end
end
Be advised that this will be slow for larger values of num
. I've also wrapped this into a function for ease of debugging. Here are a few example runs:
>> round_hack(29.1)
ans =
29
>> round_hack(29.6)
ans =
30
>> round_hack(3.4)
ans =
3
>> round_hack(3.5)
ans =
4
>> round_hack(-0.4)
ans =
0
>> round_hack(-0.6)
ans =
-1
>> round_hack(-29.7)
ans =
-30
You can check that this agrees with MATLAB's round
function for the above test cases.
Upvotes: 3
Reputation: 5190
You can do it without loop: you can use num2str
to convert the number into a string, then find the position of the .
in the string and extract the string fron its beginning up to the position of the .
; then you convert it back to a numebr with str2num
To round it you have to check the value of the first char (converted into a number) after the .
.
r=rand*100
s=num2str(r)
idx=strfind(num2str(r),'.')
v=str2num(s(idx+1))
if(v <= 5)
rounded_val=str2num(s(1:idx-1))
else
rounded_val=str2num(s(1:idx-1))+1
end
Hope this helps.
Qapla'
Upvotes: 0