On this link I found the formulas for glViewport.
<www.opengl.org/wiki/GLAPI/glViewport>

xw = (xnd + 1) (width / 2) + x;
yw = (ynd + 1) (height / 2) + y;

First test: Assume x=0 and width=800, then the window coordinates go from 0 to 799.
xnd = 1 should result in the rightmost pixel 799.
xw ( 1 ) = ( 1 + 1 ) * 800 / 2 + 0 = 800; And not 799.

I derivated the formula for normalized device to window coordinates and came to a slightly different result
to replace "width" by "(width - 1)":

xw = (xnd + 1) ((width - 1) / 2) + x;
yw = (ynd + 1) ((height - 1) / 2) + y;

Can someone confirm or disprove that?

Here my derivation for glViewport( x, y, width, height ):
So the rectangle is from (x) to (x + width - 1), and from (y) to (y + height - 1).

Example: glViewport( 400, 200, 800, 600 ) has a rectangle from x: 400 to 1199, and y: 200 to 799.

Formula for x:
xw - x = xnd * a + b; // Linear equation, resolve a and b.

1. xnd = -1, and xw = x:
x - x = -1 * a + b; -> a = b;

2. xnd = +1, and xw = x + width - 1:
x + width - 1 - x = 1 * a + b; -> width - 1 = 2 a; -> a = ( width - 1 ) / 2;

Insert in formula for x:
xw - x = xnd * (width - 1) / 2 + (width - 1) / 2;
xw = ( xnd + 1 ) * (( width - 1 ) / 2 ) + x;

Test:
1. xnd = -1: xw = ( -1 + 1 ) * (( width - 1 ) / 2 ) + x = x; -> ok, 400 by the example.
2. xnd = +1: xw = ( 1 + 1 ) * (( width - 1 ) / 2 ) + x = width - 1 + x; -> ok, 1199 by the example.

Analogical for y.