[Solved] Why Do Computer Counts from Zero.
-
You are correct! What I meant (and I admit that the language that I used was far from rigorous) was that the relative offset is unvarying. If, for example, the offset of the start of the memory allocated for the array is 100 from a location (relative addressing / stack frame relative / absolute / whatever) and each element takes up 4 address locations (e.g. bytes), then all that the compiler does for 1-based indices is to use 96 + n * 4 (because 100 - 4 = 96) instead of 100 +(n - 1) * 4 in all of its address calculations for the array; this is as simple as using 100 + n * 4 for 0-based indices. This can be extended for arrays with specifiable lower bounds e.g. in this example if lwb is the lower bound, the 0-based index offset would be 100 + (n - lwb) * 4 [or more optimally (100 - lwb * 4) + n * 4] or for 1-based index offset would be (100 - (lwb + 1) * 4) + n * 4 = (96 - lwb * 4) + n * 4.
Introduction of the lower bound would definitely negate any advantage of 0 based indexing. With no specified lower bound the cost at the instruction level would depend on the instruction set and processor, but with the instruction sets I am familiar with, 0 based indexing was definitely less expensive. Very simple case using x86 32 bit instructions and assuming that the array base in ESI and array index in EBX, accessing a 32 bit array value can be done in a single instruction in both cases: mov eax, [esi + 4*ebx] ; 0 based indexing mov eax, [esi + 4*ebx + 4] ; 1 based indexing On even the most modern x86 processor, the instruction with an offset takes more memory than the one without. On older x86 processors it would also cost CPU cycles, and on more primitive instruction sets you wouldn't even be able to encode the address calculations into a single instruction at all. One interpretation of your argument for same cost might be that in the one-based case that you just start with esi pointing to 4 bytes before, which would be true but you still have to count the cost of adjusting esi, though in some cases that calculation could be amortized across many array accesses.
-
You don't know what else the computer is doing so don't assume that there are plenty of cycles. If every app wastes 10% of the "extra" cycles it doesn't take long to bog the whole thing down.
That is assuming that the developers of system code have not already optimized the code where it can be of the most benefit. Also, it assumes that the compiler is not smart enough to do some optimizations.
-
That is assuming that the developers of system code have not already optimized the code where it can be of the most benefit. Also, it assumes that the compiler is not smart enough to do some optimizations.
Not at all. I'm saying that I could have a gazillion apps running.
-
Not at all. I'm saying that I could have a gazillion apps running.
Relative to system calls, and library calls, the code in the application usually takes up little of the resources unless you have an application that is heavily processor bound.
-
Relative to system calls, and library calls, the code in the application usually takes up little of the resources unless you have an application that is heavily processor bound.
And let's keep it that way.
-
Link to the article For More detail explanation(PDF) Counting arrays from 0 simplifies the computation of the memory address of each element. If an array is stored at a given position in memory (it’s called the address) the position of each element can be computed as
element(n) = address + n * size_of_the_element
//If you consider the first element the first, the computation becomeselement(n) = address + (n-1) * size_of_the_element
//Not a huge difference but it adds an unnecessary subtraction for each access.It was also handy back in the days when only single array indexes existed and you wanted dual indexes because everything mathematically matched up really handily without taking extra steps. for (i = 0; i < 10; i++)// Not at all like the format of older languages! { for (j = 0; j < 10: j++) { ind= i + j * 10; val[ind] = some value } } Or the other way around, find the two indexes from the current index: for (ind = 0; ind < 100; ind++) { j = ind/10; i = ind - (j * 10); }