Diferencia de C ++ correcta después del desbordamiento

I am just wondering whether differences will stay correct through an overflow. As example, I am trying to use a windows high resolution timer with QueryPerformanceFrequency(&local).

The starting value of that counter is undefined. However, the interesting bit is only the difference from the starting point. So at the beginning you record the value, and then always look at the diff. Now if I can guarantee that the difference won't be larger than a LARGE_INTEGER, is this sufficient?

Say e.g. one has 4 bits. That allows for 1...15. If the counter now starts at 14, and stops at 2, and I do 2 - 14, I should be getting 4, shouldn't I? So I needn't worry about an overflow as long the difference is smaller?

Muchas Gracias

preguntado el 08 de noviembre de 11 a las 18:11

¿No es esto algo que puedes probar tú mismo? -

@someguy: Not really. If he gets into undefined behaviour, it might seem to work in tests, and then fail under certain unpredictable instances in the final code. -

4 Respuestas

Since you are using a Windows-specific structure, your problem is easier since it only needs to run on machines that support Windows. Windows requires twos-complement arithmetic, and twos-complement arithmetic behaves on overflow in the manner you expect (overflows are computed mod 2^n).

respondido 08 nov., 11:22

I'm not going to answer the general question but rather the specific one: do you need to worry about overflows from QueryPerformanceCounter?

If you have a performance counter that is incrementing at 4 GHz, it will take 73 years for a 63-bit signed integer to wrap around to a negative number. No need to worry about overflow.

respondido 08 nov., 11:22

But the starting value isn't specified anywhere? Can one assume it starts after system start at zero? - Galletas

@Cookie, it's not specified but doesn't it make sense that it would start at zero? I just checked my own system and the counter reflects the uptime perfectly. Also the frequency is only 2.8 Mhz which makes it 1400 times less likely to overflow. - Mark Ransom

On my computer at least, the definition of LARGE_INTEGER es:

typedef union _LARGE_INTEGER {
     struct {
         DWORD LowPart;
         LONG HighPart;
     };
     LONGLONG QuadPart; 
 } LARGE_INTEGER;

The tricky part is all of those are signed. So if you have four bits, the range is (-8,7). Then if you start at 6, and stop at 0, you get a difference of -6.

However, if you cast the LONGLONG to a unsigned long long (either before or after the subtraction, either is fine), then you should get the correct answer. Converting -6 a unsigned long long resultados en 10, the correct difference.

respondido 08 nov., 11:22

Gah, and I spent most of my time on this post trying to do that stupid simple equation. Oh well. - Pato morando

Using 2's complement (the way integers are represented in computers), you can add or subtract multiple numbers -- and the result will be correct as long as it fits in the number of bits allocated. The temporary results need not fit in the allocated number of bits.

So yes, if you use an integer of N bits, you'll get the correct result as long as the difference is less than 2^N.

respondido 08 nov., 11:22

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.