2012-04-26 4 views
3

Я хочу иметь возможность «обвести» число, если оно прошло порог (не 0,5) и в противном случае округлить вниз.округление чисел с настраиваемым порогом

вот какой дерьмовый код я придумал. Есть ли встроенная функция в matlab для этого или более элегантное решение (возможно, векторизованное)?

function [ rounded_numbers ] = custom_round(input_numbers, threshold) 
%CUSTOM_ROUND rounds between 0 and 1 with threshold threshold 

    [input_rows, input_cols] = size(input_numbers); 
    rounded_numbers = zeros(input_rows, input_cols); 

    for i = 1:length(input_numbers) 
    if input_numbers(i) > threshold 
     rounded_numbers(i) = 1; 
    else 
     rounded_numbers(i) = 0; 
    end 
    end 
end 

Благодаря

ответ

1

Вот решение, в котором мы округляем от нуля, если число прошло пороговые

in = [0.2,-3.3,4.1]; 
th = 0.2; 

%# get the fractional part of the number 
frac = mod(in,1); %# positive for negative in 

%# find the sign so we know whether to round 
%# to plus or minus inf 
sig = sign(in); 

%# identify which way to round 
upIdx = frac>th; %# at threshold, we round down 

%# round towards inf if up 
out = abs(in); 
out(upIdx) = ceil(out(upIdx)); 
out(~upIdx) = floor(out(~upIdx)); 
%# re-set the sign 
out= out.*sig 
out = 
0 -4  4 

Примечания: Если номер только в диапазоне от 0 до 1, это еще проще :

%# this does exactly what your code does 
out = double(in>th); 
+0

wow Я идиот. Спасибо – waspinator

+0

@waspinator: Всегда рады помочь: P – Jonas

1

Это должно работать для любых чисел, а не только от 0 до 1. Порог должен находиться в диапазоне [0,1].

Я не тестировал с отрицательными номерами.

function [result] = custom_round(num, threshold) 

if (threshold < 0) || (threshold >= 1) 
    error('threshold input must be in the range [0,1)'); 
end 

fractional = num - floor(num); 
idx1 = fractional > threshold; 
idx2 = fractional <= threshold; 
difference = 1 - fractional; 
result = num + (difference .* idx1) - (fractional .* idx2); 

end 

Тесты

>> custom_round([0.25 0.5 0.75 1], 0.3) 
ans = 
    0  1  1  1 

>> custom_round([0.25 0.5 0.75 1], 0.8) 
ans = 
    0  0  0  1 

>> custom_round([10.25 10.5 10.75 11], 0.8) 
ans = 
    10 10 10 11 
+0

Риск здесь заключается в том, что выходные данные могут быть не целыми, что вы ожидаете, когда будете раунд. – Jonas

5

просто использовать

round(x-treshold+0.5) 

тест:

>> x = -10:0.3:10 
ans = 
    -2 -1.7 -1.4 -1.1 -0.8 -0.5 -0.2 0.1 0.4 0.7 1 1.3 1.6 1.9 


>> treshold = 0.8; % round everything up for which holds mod(x,1) >= treshold 
>> y = round(x-treshold+0.5) 

ans = 
    -2 -2 -2 -1 -1 -1 -1  0  0  0  1  1  1  2 

отрицательные числа закругленным правильно, за исключением того, на границе: -0,8 получает округляется -1 вместо 0, но это то же поведение, что и круглый, имеет: круглый (-0,5) возврат -1

Смежные вопросы