The standard form is sometimes defined with inequalities ($\leq$) and sometimes with equalities. If you want to begin with an algorithm it is useful to have equalities.
If all variables has to be equal or greater than $2016$ then you have to introduce slack variables like you proposed.
$x_1\geq 2016, x_2\geq 2016, x_3\geq 2016, \ldots, x_n\geq 2016$
becomes
$x_1-s_1= 2016, x_2-s_2= 2016, x_3-s_3= 2016, \ldots, x_n-s_n= 2016$
with $x_1, x_2,\dots, x_n, s_1, s_2, s_3, \ldots s_n \geq 0$
Here you get $n$ additional constraint. To get an initial solution artifitial variables have to be intoduced.
$x_1-s_1+a_1= 2016, x_2-s_2+a_2= 2016, x_3-s_3+a_3= 2016, \ldots, x_n-s_n+a_n= 2016$
with $x_1, x_2,\dots, x_n, s_1, s_2, s_3, \ldots s_n, a_1, a_2,\dots, a_n \geq 0$
The initial solution is $x_1=x_2=x_3=\ldots=x_n=s_1= s_2= s_3= \ldots s_n=0$
$a_1=a_2=a_3=\ldots=a_n=2016$
The decision variables are all non-negative.
This is an instance of a bilevel program, as you can see it as an optimization problem where one of the constraints is that a variable is optimal in some other optimization problem. It can be represented as a MILP via KKT conditions.
Here is a test in the MATLAB Toolbox YALMIP
https://yalmip.github.io/tutorial/bilevelprogramming/
A = randn(10,7);
b = 10*rand(10,1);
c = randn(7,1);
x = sdpvar(7,1);
optimize([0<=x<=1, A*x <= b],-c'*x)
z = value(c'*x);
y = binvar(7,1);
OuterC = [c'*x <= z - 0.1];
OuterO = sum(y);
InnerC = [0<=x<=1, x <= 1-y, A*x <= b]
InnerO = -c'*x;
solvebilevel(OuterC,OuterO,InnerC,InnerO,x)
value(x)
value(y)
This example uses the built-in naive bilevel solver. A typically better solution is to ask it to use an external MILP solver instead or manually use the kkt operator to define the MILP and then call the MILP solver
https://yalmip.github.io/example/bilevelprogrammingalternatives/
https://yalmip.github.io/command/kkt/
Best Answer
Real world Simplex codes allow variables to have a lower and upper bound. A non-basic variable can be at lower bound or at upper bound but usually not in between (there are some exceptions to this rule, sometimes these are called superbasic).
Solvers typically will tell you in their solution not only "this variable is non-basic", but more precisely "this variable is non-basic at upper bound". Otherwise you can also deduce this from the sign of the corresponding reduced cost.
Now, it depends what $x_i \le d_i$ means. Is this a constraint or a bound? If it is constraint, $x_i\ge 0$ has no finite upper bound. When solved, $x_i$ will never be "nonbasic at upper bound" but only "nonbasic at lower bound". If $x_i \le d_i$ is formulated as a bound, $x_i$ can be either NB at lower or NB at upper bound.
Also notice that presolvers typically would convert a constraint like $x_i \le d_i$ into a bound. That would make the model smaller (and reduces the size of the basis). The postsolve would report a solution that would look like the solver worked on an explicit constraint while actually, behind the scenes, it converted this to a bound.