2015-11-19 2 views
2

Q1: Будет ли разделение целого на его делитель потерять точность?C++ будет точный деление потерять точность?

int a=M*N,b=N;//M and N are random non-zero integers. 
float c=float(a)/b; 
if (c==M) 
cout<<"accurate"<<endl; 

Q2: Пропустит ли значение поплавка, потеряет точность?

float a=K;//K is a random float; 
if (a==K) 
cout<<"accurate"<<endl; 

ответ

3

Q1: Будет ли разделив число на его делитель теряют точность?

Да. Я использовал следующую программу, чтобы придумать несколько цифр:

#include <iostream> 
#include <climits> 

int main() 
{ 
    int M = 10; 
    int N = 7; 
    int inaccurateCount = 0; 
    for (; M < INT_MAX && inaccurateCount < 10; ++M) 
    { 
     int a = M*N; 
     float c = float(a)/N; 
     if (c != M) 
     { 
     std::cout << "Not accurate for M: " << M << " and N: " << N << std::endl; 
     inaccurateCount++; 
     } 
    } 

    return 0; 
} 

и вот результат:

Not accurate for M: 2396747 and N: 7 
Not accurate for M: 2396749 and N: 7 
Not accurate for M: 2396751 and N: 7 
Not accurate for M: 2396753 and N: 7 
Not accurate for M: 2396755 and N: 7 
Not accurate for M: 2396757 and N: 7 
Not accurate for M: 2396759 and N: 7 
Not accurate for M: 2396761 and N: 7 
Not accurate for M: 2396763 and N: 7 
Not accurate for M: 2396765 and N: 7 

Q2: Буду ли пропускание значения с плавающей точкой потерять точность?

Нет, не следует.

+1

'float (a)/N' только теряет точность, потому что' float (a) 'теряет точность. Когда 'a' точно представляется как float, а' N' является одним из его делителей, 'float (a)/N' должен быть точным. – user2357112

0

Это стена не может быть точным, но, чтобы получить более точные ответы, которые вы можете использовать типы значений двойной и длинный

0

Case 1: Да она теряет точность в некоторых случаях. При малых значениях M это будет точно.

Корпус 2: Нет, он не теряет своей точности.

2

Q1: Будет ли разделение целого на его делитель потерять точность?

Вы на самом деле спросил преобразования int в float потеряет precsion. Да, обычно это будет делать. На сегодняшних 32-битных (или более широких) компьютерных архитектурах int хранит 32-разрядные данные: 1 бит и плюс 31 бит. A float хранит также 32-разрядные данные, но это: 1 бит-знак, 8-разрядный показатель и 23-битная дробная часть, ср. IEEE 754 single-precision floating point format (Это может не потерять точность в 16-битной архитектуре, но я не могу это проверить.)

В зависимости от числа с плавающей запятой он будет храниться в разных вариантах, один из которых является нормированной формой, где дробная часть добавляется скрытой, так что мы получаем 24-битное значение. Это меньше, чем указано в файле int.

Например, целое число 01010101 01010101 01010101 01010101 (двоичное, только для лучшего чтения) не может быть выражено как float без потери точности. В нормализованной форме это будет 1,010101 01010101 01010101 01010101 * 2^30. Таким образом, после запятой мы имеем 30 значащих двоичных цифр, которые не могут быть сохранены в 23 бит (дробная часть) без потери точности. Фактические круглые режимы определяют, как уменьшить значение.

Обратите внимание, что это не зависит от того, действительно ли значение «высокое». Целое число 01000000 00000000 00000000 00000000 находится в нормализованной форме 1,000000 00000000 00000000 00000000 * 2^30. Это число имеет нулевые значащие бит после запятой и может храниться без потери точности.

Q2: Пропустит ли значение поплавка, потеряв точность?

No.

1

Q1: Будет ли разделив число на его делитель теряют точность?

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

Например, если N = 8388609 и M=5. У вас есть (двоичная) мантисса 100 ... 001 и умножается на 101 и заканчивается 101000 ... 0000101, но тогда последние два бита будут округлены до нуля, и вы получите ошибку в (float) (N * M), но затем, когда вы разделите их на пять, вы получите 1000 ... 00 и остаток от 100, что означает, что он должен округлить один шаг, и вы вернете исходный номер.

Q2: Пропустит ли значение поплавка, потеряв точность?

Нет, это не потеряет точность. Однако ваш код все равно не сможет определить его как точный.

Дело это может случиться, если K является NaN (например 0.0/0.0), то x также станет NaN - однако NaN не должна (должны) сравнить равных. В этом случае можно утверждать, что вы потеряли точность, и я согласен, но дело не в x=K, которое теряет точность - вы уже потеряли точность при производстве K.

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