Типизируя плавающее значение или используя функции math.h floor *? - PullRequest
0 голосов
/ 04 апреля 2010

Я кодирую реализацию Интерполяционного поиска в C.

Вопрос на самом деле довольно прост, мне нужно использовать плавающие операции для линейной интерполяции, чтобы найти правильный индекс, который в итоге будет целочисленным.

В частности, мой индекс датчика:

t = i + floor((((k-low)/(high-low)) * (j-i)));

где i, j, k, t - целые числа без знака, а high, low - double.

Будет ли это эквивалентно:

t = i + (unsigned int)(((k-low)/(high-low)) * (j-i));

Есть ли причина, по которой я бы на самом деле хотел использовать функции math.h floor * вместо простой (int) трансляции типа?

Ответы [ 3 ]

2 голосов
/ 04 апреля 2010

Они отличаются, когда значение <0. </p>

floor(-1.5) = -2.0
(int)-1.5 = 1
1 голос
/ 04 апреля 2010

Они эквивалентны только для положительных чисел. Из спецификации C99 (§6.3.1.4 / 1):

Когда конечное значение реального плавающего типа преобразуется в целочисленный тип, отличный от _Bool, дробная часть отбрасывается (то есть значение усекается до нуля). Если значение интегральная часть не может быть представлена ​​целочисленным типом, поведение не определено.

Таким образом, для положительных чисел результат приведения значения с плавающей запятой к целочисленному типу эквивалентен вызову floor, но для отрицательного числа эквивалентен вызову ceil.

0 голосов
/ 04 апреля 2010

В вашем случае они эквивалентны. Но для отрицательных чисел

g++> printf("%g %d %u\n", floor(-5.5), (int)(-5.5), (unsigned)(-5.5));
-6 -5 0

(на самом деле приведение отрицательного действительного числа ≤ -1 к целому без знака определяется реализацией (или неопределенным поведением?).)

Кроме того, floor возвращает значение типа double, поэтому i + floor(...) будет выполняться как операция с плавающей запятой вместо целочисленной операции.

...