The only things I see is that x needs to be the index of the last entry in numbers[], which is ONE LESS than "the amount of numbers". Also, the initialization of w needs to be inside the x loop. Suppose n is the actual number of data values in numbers. Then:
int x = n-1;
while (x > 0)
{
int w = x-1;
whlile (w>=0)
{
...etc.
Then you can lose the w2 and w settings at the top. w is only needed inside the x loop, so that's where it should be declared.
In your original code, w is aways being set to w2. The first two outer loops work as planned, moving the largest element to to numbers[n-1] and the second largest to numbers[n-2]. On the third iteration, though, w is still n-2 at entry and the inner loop will swap the second largest element down to numbers[n-3] on the very first compare. That happens because x is n-3 on that loop, but w was set back to w2, which is equal to n-2.
You might want to pick better variable names, since "w" and "x" aren't exactly self-explanatory. Maybe ix_left and ix_right, or iLeft and iRight? That would emphasize that w must be less than x at all times in the inner loop.
Edit: Kozak is right. This isn't really an insertion sort. I believe the technical name is "selection sort" since it selects the largest element from the unsorted portion of the data on each inner loop, placing it in the correct position. Selection and insertion sorts have roughly the same runtime, but opposite orientation:
An insertion sort removes elements sequentially from the unsorted list and finds the place to insert each into the sorted list. A selection sort removes elements form the list in their final sort order and adds them sequentially to the sorted lest.
The insertion sort might look like:
int xnext = 1;
while (xnext < n)
{
int nextval = numbers[xnext ];
int xinsert = xnext ;
while (xinsert > 0 && nextval < numbers[xinsert-1])
{
--xinsert;
numbers[xinsert+1] = numbers[xleft];
}
numbers[xinsert] = nextval;
}
That's just typed on-the-fly so there may be errors. The general idea is that numbers[0] is a starting sorted output list, and values numbers[1], numbers[2], etc. are inserted into that list on each iteration of the outer loop. The inner loop searches from right to left for where to put the new number, and moves bigger values to the right to make room for the insert.