Frustrating Math Problem, results not as expected (EDQ) - c++

Here is my code, throttle comes out to -18 when I run the program, and when I do the math I get 77.941... which is what I'm looking for. I know this is an EDQ "Extremely Dumb Question", and I am most likely to experience a FIF, "Fist In Forehead" moment any minute but I am stuck on it for now. FYI, programming it on an Atmega 328P using Arduino IDE on Windows 10.
Following example prints -18 and according to my calcualtions it should be 77.941...
int throttle = (((800 - 270) * 100) / 680);
Serial.println(throttle);
This is the visualized code...
throttle = (((throttleSensor - oldMinValue) * (newMax - newMin)) / (oldMax - oldMin));
I am trying to do this, Convert a number range to another range, maintaining ratio
Also, I should add, it works fine when the result is below 47, above that it flips to a negative number.

The short answer is, (800 - 270) * 100 = 53000. which is too large a number for the space that was allocated for the calculation results, integer overflow.
so changing the code from this...
int throttle = (((800 - 270) * 100) / 680);
to this...
long largeValue = 100;
int throttle = (((800 - 270) * largeValue) / 680);
fixes the problem. The number 100 or value of (newMax - newMin) has to be a "long" or the processor will miscalculate. Someone, please correct me on this if need be or post a better answer if you got one. Also if someone has a better suggestion for the title so it can be easier found for future people with the same problem, go ahead and commend it below.
Thanks to the StackOverflow community for helping me solve this issue!

as #edgar_wideman answer suggest your sub result (53000) does not fit into 16bit integer <-32768,+32767>. You can avoid long use by bitshifting (dividing by power of 2) like this:
int sh=1; // shift stuff so it fits 16 bit
int throttle = (((800 - 270) * (100>>sh)) / (680>>sh));

This might not be exactly what you are looking for, but there is a function for changing values from one range to an other.
int y = map(value, minOld, maxOld, minNew, maxNew);
for example:
int y = map(10, 0, 50, 0, 100); // y would be 20

Related

How to check if a value within a range is multiple of a value from another range?

Let say I've a system that distribute 8820 values into 96 values, rounding using Banker's Round (call them pulse). The formula is:
pulse = BankerRound(8820 * i/96), with i[0,96[
Thus, this is the list of pulses:
0
92
184
276
368
459
551
643
735
827
919
1011
1102
1194
1286
1378
1470
1562
1654
1746
1838
1929
2021
2113
2205
2297
2389
2481
2572
2664
2756
2848
2940
3032
3124
3216
3308
3399
3491
3583
3675
3767
3859
3951
4042
4134
4226
4318
4410
4502
4594
4686
4778
4869
4961
5053
5145
5237
5329
5421
5512
5604
5696
5788
5880
5972
6064
6156
6248
6339
6431
6523
6615
6707
6799
6891
6982
7074
7166
7258
7350
7442
7534
7626
7718
7809
7901
7993
8085
8177
8269
8361
8452
8544
8636
8728
Now, suppose the system doesn't send to me these pulses directly. Instead, it send these pulse in 8820th (call them tick):
tick = value * 1/8820
The list of the ticks I get become:
0
0.010430839
0.020861678
0.031292517
0.041723356
0.052040816
0.062471655
0.072902494
0.083333333
0.093764172
0.104195011
0.11462585
0.124943311
0.13537415
0.145804989
0.156235828
0.166666667
0.177097506
0.187528345
0.197959184
0.208390023
0.218707483
0.229138322
0.239569161
0.25
0.260430839
0.270861678
0.281292517
0.291609977
0.302040816
0.312471655
0.322902494
0.333333333
0.343764172
0.354195011
0.36462585
0.375056689
0.38537415
0.395804989
0.406235828
0.416666667
0.427097506
0.437528345
0.447959184
0.458276644
0.468707483
0.479138322
0.489569161
0.5
0.510430839
0.520861678
0.531292517
0.541723356
0.552040816
0.562471655
0.572902494
0.583333333
0.593764172
0.604195011
0.61462585
0.624943311
0.63537415
0.645804989
0.656235828
0.666666667
0.677097506
0.687528345
0.697959184
0.708390023
0.718707483
0.729138322
0.739569161
0.75
0.760430839
0.770861678
0.781292517
0.791609977
0.802040816
0.812471655
0.822902494
0.833333333
0.843764172
0.854195011
0.86462585
0.875056689
0.88537415
0.895804989
0.906235828
0.916666667
0.927097506
0.937528345
0.947959184
0.958276644
0.968707483
0.979138322
0.989569161
Unfortunately, between these ticks it sends to me also fake ticks, that aren't multiply of original pulses. Such as 0,029024943, which is multiply of 256, which isn't in the pulse lists.
How can I find from this list which ticks are valid and which are fake?
I don't have the pulse list to compare with during the process, since 8820 will change during the time, so I don't have a list to compare step by step. I need to deduce it from ticks at each iteration.
What's the best math approch to this? Maybe reasoning only in tick and not pulse.
I've thought to find the closer error between nearest integer pulse and prev/next tick. Here in C++:
double pulse = tick * 96.;
double prevpulse = (tick - 1/8820.) * 96.;
double nextpulse = (tick + 1/8820.) * 96.;
int pulseRounded=round(pulse);
int buffer=lrint(tick * 8820.);
double pulseABS = abs(pulse - pulseRounded);
double prevpulseABS = abs(prevpulse - pulseRounded);
double nextpulseABS = abs(nextpulse - pulseRounded);
if (nextpulseABS > pulseABS && prevpulseABS > pulseABS) {
// is pulse
}
but for example tick 0.0417234 (pulse 368) fails since the prev tick error seems to be closer than it: prevpulseABS error (0.00543795) is smaller than pulseABS error (0.0054464).
That's because this comparison doesn't care about rounding I guess.
NEW POST:
Alright. Based on what I now understand, here's my revised answer.
You have the information you need to build a list of good values. Each time you switch to a new track:
vector<double> good_list;
good_list.reserve(96);
for(int i = 0; i < 96; i++)
good_list.push_back(BankerRound(8820.0 * i / 96.0) / 8820.0);
Then, each time you want to validate the input:
auto iter = find(good_list.begin(), good_list.end(), input);
if(iter != good_list.end()) //It's a match!
cout << "Happy days! It's a match!" << endl;
else
cout << "Oh bother. It's not a match." << endl;
The problem with mathematically determining the correct pulses is the BankerRound() function which will introduce an ever-growing error the higher values you input. You would then need a formula for a formula, and that's getting out of my wheelhouse. Or, you could keep track of the differences between successive values. Most of them would be the same. You'd only have to check between two possible errors. But that falls apart if you can jump tracks or jump around in one track.
OLD POST:
If I understand the question right, the only information you're getting should be coming in the form of (p/v = y) where you know 'y' (that's each element in your list of ticks you get from the device) and you know that 'p' is the Pulse and 'v' is the Values per Beat, but you don't know what either of them are. So, pulling one point of data from your post, you might have an equation like this:
p/v = 0.010430839
'v', in all the examples you've used thus far, is 8820, but from what I understand, that value is not a guaranteed constant. The next question then is: Do you have a way of determining what 'v' is before you start getting all these decimal values? If you do, you can work out mathematically what the smallest error can be (1/v) then take your decimal information, multiply it by 'v', round it to the nearest whole number and check to see if the difference between its rounded form and its non-rounded form falls in the bounds of your calculated error like so:
double input; //let input be elements in your list of doubles, such as 0.010430839
double allowed_error = 1.0 / values_per_beat;
double proposed = input * values_per_beat;
double rounded = std::round(proposed);
if(abs(rounded - proposed) < allowed_error){cout << "It's good!" << endl;}
If, however, you are not able to ascertain the values_per_beat ahead of time, then this becomes a statistical question. You must accumulate enough data samples, remove the outliers (the few that vary from the norm) and use that data. But that approach will not be realtime, which, given the terms you've been using (values per beat, bpm, the value 44100) it sounds like realtime might be what you're after.
Playing around with Excel, I think you want to multiply up to (what should be) whole numbers rather than looking for closest pulses.
Tick Pulse i Error OK
Tick*8820 Pulse*96/8820 ABS( i - INT( i+0.05 ) ) Error < 0.01
------------ ------------ ------------- ------------------------ ------------
0.029024943 255.9999973 2.786394528 0.786394528 FALSE
0.0417234 368.000388 4.0054464 0.0054464 TRUE
0 0 0 0 TRUE
0.010430839 91.99999998 1.001360544 0.001360544 TRUE
0.020861678 184 2.002721088 0.002721088 TRUE
0.031292517 275.9999999 3.004081632 0.004081632 TRUE
0.041723356 367.9999999 4.005442176 0.005442176 TRUE
0.052040816 458.9999971 4.995918336 0.004081664 TRUE
0.062471655 550.9999971 5.99727888 0.00272112 TRUE
0.072902494 642.9999971 6.998639424 0.001360576 TRUE
0.083333333 734.9999971 7.999999968 3.2E-08 TRUE
The table shows your two "problem" cases (the real wrong value, 256, and the one your code gets wrong, 368) followed by the first few "good" values.
If both 8820s vary at the same time, then obviously they will cancel out, and i will just be Tick*96.
The Error term is the difference between the calculated i and the nearest integer; if this less than 0.01, then it is a "good" value.
NOTE: the 0.05 and 0.01 values were chosen somewhat arbitrarily (aka inspired first time guess based on the numbers): adjust if needed. Although I've only shown the first few rows, all the 96 "good" values you gave show as TRUE.
The code (completely untested) would be something like:
double pulse = tick * 8820.0 ;
double i = pulse * 96.0 / 8820.0 ;
double error = abs( i - floor( i + 0.05 ) ) ;
if( error < 0.05 ) {
// is pulse
}
I assume your initializing your pulses in a for-loop, using int i as loop variable; then the problem is this line:
BankerRound(8820 * i/96);
8820 * i / 96 is an all integer operation and the result is integer again, cutting off the remainder (so in effect, always rounding towards zero already), and BankerRound actually has nothing to round any more. Try this instead:
BankerRound(8820 * i / 96.0);
Same problem applies if you are trying to calculate prev and next pulse, as you actually subtract and add 0 (again, 1/8820 is all integer and results in 0).
Edit:
From what I read from the commments, the 'system' is not – as I assumed previously – modifiable. Actually, it calculates ticks in the form of n / 96.0, n &#x220a [0, 96) in ℕ
however including some kind of internal rounding appearently independent from the sample frequency, so there is some difference to the true value of n/96.0 and the ticks multiplied by 96 do not deliver exactly the integral values in [0, 96) (thanks KarstenKoop). And some of the delivered samples are simply invalid...
So the task is to detect, if tick * 96 is close enough to an integral value to be accepted as valid.
So we need to check:
double value = tick * 96.0;
bool isValid
= value - floor(value) < threshold
|| ceil(value) - value < threshold;
with some appropriately defined threshold. Assuming the values really are calculated as
double tick = round(8820*i/96.0)/8820.0;
then the maximal deviation would be slightly greater than 0.00544 (see below for a more exact value), thresholds somewhere in the sizes of 0.006, 0.0055, 0.00545, ... might be a choice.
Rounding might be a matter of internally used number of bits for the sensor value (if we have 13 bits available, ticks might actually be calculated as floor(8192 * i / 96.0) / 8192.0 with 8192 being 1 << 13 &ndash and floor accounting to integer division; just a guess...).
The exact value of the maximal deviation, using 8820 as factor, as exact as representable by double, was:
0.00544217687075132516838493756949901580810546875
The multiplication by 96 is actually not necessary, you can compare directly with the threshold divided by 96, which would be:
0.0000566893424036596371706764330156147480010986328125

VHDL: Cosine Lookup Table

I am working with VGA on my Basys3 FPGA, and I currently want to draw a zone plate, for which the equation is (1 + cos(k*r^2)) / 2, where r is the distance from the plate center, and k=2*pi/lambda is the wavenumber, which determines the scale of the plate. I am guessing the best course of action would be to use a cosine LUT, but I really have no idea how to create one. I somewhat understand the idea behind it, but I don't know how to write one and what values it should contain.
This is the code I am trying to test out:
The only problem with this now is that I do not know what values to fill the memory_type :=() with, so that it will equal the k*r^2 from the formula.
architecture Behavioral of VGAdraw is
signal i : integer range 0 to 29:=0;
signal r : integer :=2;
type memory_type is array (0 to 29) of integer range -128 to 127;
signal cosine : memory_type :=();
begin
process(CLK)
begin
if (CLK'EVENT and CLK = '1') then
if (cntHor >= 0) AND (cntHor <= cstHorAL - 1) then
RED <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
GREEN <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
BLUE <= conv_std_logic_vector ((1 - cosine (i)) / 2, 8) (7 downto 4);
i <= i + 1;
else
RED <= "0000";
GREEN <= "0000";
BLUE <= "0000";
end if;
end if;
end process;
end Behavioral;
cntHor - horizontal counter
cstHorAL - nr of pixels on an active line
I cannot post the image itself due to lack of reputation, but this is what it should look like: http://handforgedvideo.com/wp-content/uploads/2013/02/1920x1080p24_Luma_Zone_Plate_Main.png
Any help is appreciated.
Thank you!
Your general code isn't too far off, but as Morten pointed out, you don't specify the format of the input (theta) or the outputs (sin_data and cos_data). Are they fixed point values? Where's the fractional point? Are they just integers?
You say:
I am guessing the best course of action would be to use a cosine LUT, but I really have no idea how to create one.
I presume you mean by "LUT" a generic "lookup table". The use of "LUT" is ambiguous in your question since you also mention the Basys3. In FPGA literature, LUT is a specific type of logic structure on an FPGA. It also means "lookup table", but the size and complexity are limited to a few digital inputs. There are no "cosine LUT" objects available. I just wanted to be clear that by "LUT" you mean a generic lookup table.
Now, your code isn't too far off. It is indeed a lookup table to pass in theta and output sin_data and cos_data. The questions are a) whether or not your outputs accurately represent the function and b) whether or not your implementation is the most efficient.
For the former, I'm not sure since you don't specify the input and output format. Also, you don't specify the mapping between ϴ and your function. Is ϴ the argument to cos()? Or is it k? Or is it λ?
For the latter, take a look at Xilinx UG901. It gives examples of how to infer ROMs (see the 'ROM HDL Coding Techniques' section). Your code, as written, would probably be the least efficient method. You need two lookup tables with 4K entries each (sin_data and cos_data), so two 4K x 12bit. You'd be better off with a ROM build from a block RAM.

For Loops for a Time Class

I am trying to write a for loop for a time class. Where if the minutes entered are over 60, 60 is subtracted from the total minutes and hours is incremented by 1 until the final minutes left is less than 60 . I was doing if statements like
if (m > 59){
m = m - 60;
h++;
if (m > 59)... etc..
but that doesn't cover every case and I feel like I should know how to do this for loop but I can't figure it out. Any help would be appreciated, thanks
Well if it doesn't have to be implemented using loops, you could do simply
h = m / 60;
m = m % 60;
It is the fastest and cleanest way to do that, I suppose.
Not really sure whether you want to do anything else inside the loops. If so, this won't help you very much.
Edit:
Here is some explanation of how it works.
What m / 60 does is called integer division. It returns floor of the expression. So for example if m = 131 than m / 60 = 2.
The second expression uses the modulo operator. Basically it finds the reminder after division. Back to our example, m % 60 = 11 since m can be written as m = 60 * 2 + 11 = 131. For further information please refer to wiki.
#Jendas has a good simple answer to the overall problem, but if you want to keep with this format but fix your issue with loops, you could put the whole thing in a while loop instead of individual if statements:
while(m >59)
{
m = m - 60;
h++;
// do anything else you need to take care of
}
// finishing statements
h = 0;
while (m >= 60)
{
m = m - 60;
h++;
}
You probably want to use >= 60 instead of 59.
Also, as Jendas rightly suggested you might want to research a little about the modulus operator '%'

How do I convert this function into a loop?

I have an array of letters of an unknown number of elements which contains lower case letters. I have written a function for converting a lower case number to its ASCII value
int returnVal (char x)
{
return (int) x;
}
I am trying to combine all of these values into one number. Subtracting 87 from each of these means that the value is always a 2 digit number. I am able to combine an array made up if two elements by:
returnVal (foo[0]) - 87) + returnVal (foo[1] - 87) * 100
an array made up of three elements by
returnVal (foo[0]) - 87) + returnVal (foo[1] -87) * 100 + returnVal (foo[2] - 87) * 100 * 100
I am multiplying each element by 100^its position in the array and summing them. This means that [a,b,c] would become 121110 (yes, the 'flip' having the value for 'c' first and 'a' last is intentional). Could anybody programme this (for an array of an unknown number of elements)?
EDIT: I have received no form of schooling at programming/computer science at any pojnt in my life, this is not homework. I am trying to teach myself and I have got stuck; I don't know anybody in person who I could go to for help so I asked here, apologies to those of you who are offended.
EDIT2: I know that this opinion is going to annoy a lot of people; what is the purpose of stackoverflow.com if it is not to exchange information? If I were a child who was stuck with my homework (I'm not) surely that is a valid reason for using stack overflow? Many people on this website seem to have the mindset that if a problem is asked by a beginner then it is not worth answering, which is completely fine because your time is your own. However, what genuinely bugs me is the people who see a question which they deem trivial and say "homework" and vote it down immediately. I think that this website would be far better if there wasn't an "minimum-level" knowledge required in order to ask questions, the "elitist" mindset is just childish in my opinion.
Since this is a learning exercise, here are some hints for you to complete the task yourself:
Prepare a value that will server as the "running total" for your number so far.
Start the running total at zero.
When you convert a number, say, "1234", to an int, this value would first become 1, then 12, then 123, and finally 1234
The final value of the running total is your end result
To go from a previous value to the next, multiply the prior value by ten, and add the value of the current digit to it
Your returnVal does not make sense, because in C you can very often avoid an explicit conversion of char to int. You can definitely avoid it in this case.
Making a function int digit(char c) that returns a value of decimal digit, i.e. c-'a', would be a lot more useful, because it would let you get rid of your c-87 in multiple spots.
char array[SIZE];
long factor=1;
long result=0;
for(int i=0; i<SIZE; i++)
{
result+=returnVal(foo[i])-87)*factor;
factor*=100;
}
This should work for as long as long is large enough to hold the value of 100^the position and, of course, as long as the result does not overflow.

Which language understands 'variable a = 0 , 20, ..., 300'?

Which language is smart so that it could understand variable a = 0 , 20, ..., 300 ? so you could easily create arrays with it giving step start var last var (or, better no last variable (a la infinite array)) and not only for numbers (but even complex numbers and custom structures like Sedenion's which you would probably define on your own as a class or whatever...)
Point is, find a language or algorithm usable in a language that can cach the law of how array of variables you've given (or params of that variables) change. And compose using that law a structure from which you would be able to get any variable(s).
To everyone - examples you provide are very helpful for all beginners out there. And at the same time are the basic knowledge required to build such 'Smart Array' class. So thank you wary much for your enthusiastic help.
As JeffSahol noticed
all possible rules might include some
that require evaluation of some/all
existing members to generate the nth
member.
So it is a hard Question. And I think language that would do it 'Naturally' would be great to play\work with, hopefully not only for mathematicians.
Haskell:
Prelude> let a=[0,20..300]
Prelude> a
[0,20,40,60,80,100,120,140,160,180,200,220,240,260,280,300]
btw: infinite lists are possible, too:
Prelude> let a=[0,20..]
Prelude> take 20 a
[0,20,40,60,80,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380]
Excel:
Write 0 in A1
Write 20 in A2
Select A1:2
Drag the corner downwards
MatLab:
a = [0:20:300]
F#:
> let a = [|0..20..300|];;
val a : int [] =
[|0; 20; 40; 60; 80; 100; 120; 140; 160; 180; 200; 220; 240; 260; 280; 300|]
With complex numbers:
let c1 = Complex.Create( 0.0, 0.0)
let c2 = Complex.Create(10.0, 10.0)
let a = [|c1..c2|]
val a : Complex [] =
[|0r+0i; 1r+0i; 2r+0i; 3r+0i; 4r+0i; 5r+0i; 6r+0i; 7r+0i; 8r+0i; 9r+0i; 10r+0i|]
As you can see it increments only the real part.
If the step is a complex number too, it will increment the real part AND the imaginary part, till the last var real part has been reached:
let step = Complex.Create(2.0, 1.0)
let a = [|c1..step..c2|]
val a: Complex [] =
[|0r+0i; 2r+1i; 4r+2i; 6r+3i; 8r+4i; 10r+5i|]
Note that if this behavior doesn't match your needs you still can overload (..) and (.. ..) operators. E.g. you want that it increments the imaginary part instead of the real part:
let (..) (c1:Complex) (c2:Complex) =
seq {
for i in 0..int(c2.i-c1.i) do
yield Complex.Create(c1.r, c1.i + float i)
}
let a = [|c1..c2|]
val a : Complex [] =
[|0r+0i; 0r+1i; 0r+2i; 0r+3i; 0r+4i; 0r+5i; 0r+6i; 0r+7i; 0r+8i; 0r+9i; 0r+10i|]
And PHP:
$a = range(1,300,20);
Wait...
Python:
print range(0, 320, 20)
gives
[0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300]
Props to the comments (I knew there was a more succinct way :P)
Scala:
scala> val a = 0 to 100 by 20
a: scala.collection.immutable.Range = Range(0, 20, 40, 60, 80, 100)
scala> a foreach println
0
20
40
60
80
100
Infinite Lists:
scala> val b = Stream from 1
b: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> b take 5 foreach println
1
2
3
4
5
In python you have
a = xrange(start, stop, step)
(or simply range in python 3)
This gives you an iterator from start to stop. It can be infinite since it is built lazily.
>>> a = xrange(0, 300, 20)
>>> for item in a: print item
...
0
20
40
60
80
100
120
140
160
180
200
220
240
260
280
And C++ too [use FC++ library]:
// List is different from STL list
List<int> integers = enumFrom(1); // Lazy list of all numbers starting from 1
// filter and ptr_to_fun definitions provided by FC++
// The idea is to _filter_ prime numbers in this case
// prime is user provided routine that checks if a number is prime
// So the end result is a list of infinite primes :)
List<int> filtered_nums = filter( ptr_to_fun(&prime), integers );
FC++ lazy list implementation: http://www.cc.gatech.edu/~yannis/fc++/New/new_list_implementation.html
More details: http://www.cc.gatech.edu/~yannis/fc++/
Arpan
Groovy,
assert [ 1, *3..5, 7, *9..<12 ] == [1,3,4,5,7,9,10,11]
The SWYM language, which appears to no longer be online, could infer arithmetic and geometric progressions from a few example items and generate an appropriate list.
I believe the syntax in perl6 is start ... *+increment_value, end
You should instead use math.
- (int) infiniteList: (int)x
{
return (x*20);
}
The "smart" arrays use this format since I seriously doubt Haskel could let you do this:
a[1] = 15
after defining a.
C# for example does implement Enumerable.Range(int start, int count), PHP offers the function range(mixed low, mixed high, number step), ... There are programming languages that are "smart" enough.
Beside that, an infinite array is pretty much useless - it's not infinite at all but all-memory-consuming.
You cannot do this enumerating simply with complex numbers as there is no direct successor or predecessor for a given number. Edit: This does not mean that you cannot compare complex numbers or create an array with a specified step!
I may be misunderstanding the question, but the answers that specify way to code the specific example you gave (counting by 20's) don't really meet the requirement that the array "cache" an arbitrary rule for generating array members...it seems that almost any complete solution would require a custom collection class that allows generation of the members with a delegated function/method, especially since all possible rules might include some that require evaluation of some/all existing members to generate the nth member.
Just about any program language can give you this sequence. The question is what syntax you want to use to express it. For example, in C# you can write:
Enumerable.Range(0, 300).Where(x => (x % 20) == 0)
or
for (int i = 0; i < 300; i += 20) yield return i;
or encapsulated in a class:
new ArithmaticSequence(0, 301, 20);
or in a method in a static class:
Enumerable2.ArithmaticSequence(0, 301, 20);
So, what is your criteria?
Assembly:
Assuming edi contains the address of the desired array:
xor eax, eax
loop_location:
mov [edi], eax
add edi, #4
add eax, #20
cmp eax, #300
jl loop_location
MATLAB
it is not a Programming language itself but its a tool but still u can use it like a programming language.
It is built for such Mathematics operations to easily arrays are a breeze there :)
a = 0:1:20;
creates an array from 0 to 20 with an increment of 1.
instead of the number 1 you can also provide any value/operation for the increment
Php always does things much simpler, and sometimes dangerously simple too :)
Well… Java is the only language I've ever seriously used that couldn't do that (although I believe using a Vector instead of an Array allowed that).