简体   繁体   中英

C++ will exact division lose precision?

Q1:Will dividing a integer by its divisor lose precision ?

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:Will passing a float value lose precision ?

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

Q1:Will dividing a integer by its divisor lose precision ?

Yes. I used the following program to come up with some numbers:

#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;
}

and here's the output:

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:Will passing a float value lose precision ?

No, it shouldn't.

Q1:Will dividing a integer by its divisor lose precision ?

You actually asked if converting a int to a float will lose precsion. Yes, it will typically do that. On today 32-bit (or wider) computer architectures an int stores 32-bit of data: 1 bit sign plus 31 bit significand. A float stores also 32-bit of data, but these are: 1 bit sign, 8 bit exponent, and 23 bit fractional part, cf. IEEE 754 single-precision floating point format (It might not lose precision on a 16-bit architecture, but I can't check that.)

Depending on the floating point number it will be stored in different represantations, one is the normalized form, where the fractional part is prepended by a hidden one, so that, we get a 24 bit significand. This is less than as stored in an int .

For example the integer 01010101 01010101 01010101 01010101 (binary, space only for better reading) cannot be expressed as float without loosing precision. In normalized form this would be 1,010101 01010101 01010101 01010101 * 2^30. So we have 30 significand binary digits after the comma, which cannot be stored in 23 bit (fractional part) without losing precision. The actual round modes defines how the value is shortened.

Note, that it does not depends on if the value is actually "high". The integer 01000000 00000000 00000000 00000000 is in normalized form 1,000000 00000000 00000000 00000000 * 2^30. This number has zero significant bits after the comma and can be stored without losing precision.

Q2: Will passing a float value lose precision ?

No.

Q1:Will dividing a integer by its divisor lose precision ?

If a is to large it might loose precision, otherwise (if a is small enough to be exactly represented as a float) it will not. The loss of precision may actually happen already when you convert a . Also the division will loose precision, but sometimes it could be that these losses of precision will cancel each other.

For example if N = 8388609 and M=5 . You have the (binary) mantissa 100...001 and multiply with 101 and end up with 101000...0000101, but then the last two bits will be rounded to zero and you get an error in (float)(N*M), but then when you divide by five, you get 1000...00 and a remainder of 100, which means that it should round up one step and you get back the original number.

Q2:Will passing a float value lose precision ?

No, it will not lose precision. However your code could still fail to identify it as accurate.

The case this could happen is if K is a NaN (for example 0.0/0.0 ), then x will also become a NaN - however NaN shouldn't (need to) compare equals. In this case one could argue that you lost precision and I agree, but it's not at the point x=K that looses precision - you already lost precision when producing K .

它不是很准确,但是要获得更准确的答案,您可以使用double和long值类型

Case 1: Yes it loses precision in some cases. For small values of M it will be accurate.

Case 2: No it doesn't lose its precision.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM