PDA

View Full Version : need more precision in C++ (more than 8-byte long double)


brett
15th January 2004, 18:13
I'm having a problem with not getting enough precision in my frame calculations.

Visual C++ 6.0 only gives me 64-bit long doubles. 29.97 FPS is actually:

29.9700299700299700299700... FPS

but the closest I can get is:

29.9700299700299690 FPS

This becomes a problem when I'm trying to calculate the position of a frame down to 1/1000 sec.

Frame 13005 (29.970 FPS)
actual position = 433.93350 sec
posion reported in VDub = 433.934 sec
posion calculated in C++ = 433.933 sec

Even if I display just the simple calculation:
13005.0 / 30000 * 1001
I should get 433.9335, but it gives:
433.933499999999980.

So, it rounds down. I need to an accurate result to match VDub's calculations.

Proff
15th January 2004, 18:49
I know the Intel C++ compiler supports the option '/Qlong_double' that makes the 'long double' type 80 bits..

But if this still isn't enough or you can't use this compiler, u perhaps need a representation of this framerate with 2 integers that must be divided by eachother to get the correct value.

Why is this framerate 29.9700299700299700299700 anyway? How is it calculated to begin with?

I read somewhere that it is actually 29.97002616 per definition.. But don't know if that is true..

hope this helps,

Prof

PS. I really do get 433.93350000000 out of that calculation in VS6 (with both VC6 + ICL8 compilers).

mpucoder
15th January 2004, 19:55
The framerate you quoted is what is know as a repeating decimal, no amount of precision will express it exactly. But it is a rational number, 30000 / 1001
Use the "MAD" (Multiply Add Divide) rule and you'll have no problem.

But, that is NOT the true NTSC framerate, only an approximation. The true rate is based on the color subcarrier frequency (which, in turn, is based on the audio carrier frequency).
Fcs (color subcarrier) = 3579545 Hz
With 227.5 cycles of color subcarrier per line, and 525 lines per frame, there are 119437.5 cycles of color subcarrier per frame.
So, the framerate is 3579545 / 119437.5 = 29.97002616
Ratiometrically it is 7159090 / 238875, which simplifies to 1431818 / 47775

Now for a little more fun. ITU 601, which specifies how to digitize both PAL and NTSC, uses a sample rate of 13.5 MHz. It also specifies 858 samples (including non-video) per horizontal line. So the frame rate derived from this is slightly different.
13500000 / 858 / 525 = 29.97002996