Прошу ответить на вопрос.
Язык СИ, формула округления целых чисел. Пусть, например, нужно вычислить
где
x и
y целые числа. И все вычисления чтоб были целочисленными. Умножаю
0.3 на степень двойки, например, на
16.
Формула, заменяющая деление на 16 и дающая правильное приближение, а не такое, как при операции деления целых чисел:
y = ((5 * x) + 8) >> 4;Я написал тест. На моём компьютере, видимо, дополнительный код для отрицательных чисел.
int main()
{
int a[]={ 6, 7, 8, 9, 10, 14, 15, 16, 17, 18,
-6,-7,-8,-9,-10,-14,-15,-16,-17,-18};
int x, y, i;
for(i=0; i<(sizeof(a)/sizeof(a[0])); i++){
x = a[i];
y = (x + 8) >> 4; // y=x/16
printf("%3d/16=%2d\n", x, y);
}
exit(0);
}
Распечатка.
6/16= 0
7/16= 0
8/16= 1
9/16= 1
10/16= 1
14/16= 1
15/16= 1
16/16= 1
17/16= 1
18/16= 1
-6/16= 0
-7/16= 0
-8/16= 0
-9/16=-1
-10/16=-1
-14/16=-1
-15/16=-1
-16/16=-1
-17/16=-1
-18/16=-1
Код:
Пример работы формулы y = (x + 8) >> 4; для x=-9 и x=-10 в дополнительном коде.
Пример y = ((-9) + 8) >> 4
8 = |0|0|0|0|1|0|0|0|
-9 = |1|1|1|1|0|1|1|1|
8 + (-9) = |1|1|1|1|1|1|1|1| = -1
8 + (-9) >> 4 = |1|1|1|1|1|1|1|1| = -1
Пример y = ((-10) + 8) >> 4
8 = |0|0|0|0|1|0|0|0|
-10 = |1|1|1|1|0|1|1|0|
8 + (-10) = |1|1|1|1|1|1|1|0| = -2
(8 + (-10)) >> 4 = |1|1|1|1|1|1|1|1| = -1
Вопрос: всегда ли, на любых ли компьютерах эта формула даст правильное приближение для отрицательных чисел? Если существуют компьютеры, где отрицательные числа представлены точно так же, как положительные (модуль), со специальным знаковым битом, то на таких, по-моему, не сработает.
Для округления
float-чисел до целых я применяю формулу:
double sum;
int s;
if(sum >= 0) sum += 0.5;
else sum -= 0.5;
s = (int)sum;