Forums > MaxMSP

is max bad at math?

September 4, 2009 | 5:45 am

I think I’ve gone crazy. I’m quite sure that 100 * .01 = 1. Shouldn’t the following patch have the same answer in all the number boxes? Has this issue been discussed before? I can’t find anything on it.
{
"patcher" : {
"fileversion" : 1,
"rect" : [ 270.0, 423.0, 640.0, 506.0 ],
"bglocked" : 0,
"defrect" : [ 270.0, 423.0, 640.0, 506.0 ],
"openrect" : [ 0.0, 0.0, 0.0, 0.0 ],
"openinpresentation" : 0,
"default_fontsize" : 9.0,
"default_fontface" : 0,
"default_fontname" : "Arial",
"gridonopen" : 0,
"gridsize" : [ 15.0, 15.0 ],
"gridsnaponopen" : 0,
"toolbarvisible" : 1,
"boxanimatetime" : 200,
"imprint" : 0,
"boxes" : [ {
"box" : {
"maxclass" : "newobj",
"text" : "print",
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 495.0, 256.0, 28.0, 17.0 ],
"numoutlets" : 0,
"id" : "obj-13",
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "f",
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 417.0, 254.0, 32.5, 17.0 ],
"numoutlets" : 1,
"id" : "obj-12",
"outlettype" : [ "float" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "number",
"presentation_rect" : [ 417.0, 276.0, 0.0, 0.0 ],
"bordercolor" : [ 0.87451, 0.25098, 0.717647, 1.0 ],
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 417.0, 276.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-11",
"outlettype" : [ "int", "bang" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "number",
"presentation_rect" : [ 362.0, 274.0, 0.0, 0.0 ],
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 68.0, 274.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-10",
"outlettype" : [ "int", "bang" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "/ 100",
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 68.0, 193.0, 32.5, 17.0 ],
"numoutlets" : 1,
"id" : "obj-9",
"outlettype" : [ "int" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "101",
"presentation_rect" : [ 358.0, 137.0, 0.0, 0.0 ],
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 351.0, 112.0, 32.5, 15.0 ],
"numoutlets" : 1,
"id" : "obj-8",
"outlettype" : [ "" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "100",
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 290.0, 112.0, 32.5, 15.0 ],
"numoutlets" : 1,
"id" : "obj-7",
"outlettype" : [ "" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "99",
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 223.0, 112.0, 32.5, 15.0 ],
"numoutlets" : 1,
"id" : "obj-6",
"outlettype" : [ "" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "number",
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 256.0, 275.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-5",
"outlettype" : [ "int", "bang" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "* 0.01",
"fontsize" : 9.0,
"numinlets" : 2,
"patching_rect" : [ 253.0, 186.0, 34.0, 17.0 ],
"numoutlets" : 1,
"id" : "obj-4",
"outlettype" : [ "float" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "flonum",
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 188.0, 274.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-3",
"outlettype" : [ "float", "bang" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "number",
"bordercolor" : [ 0.87451, 0.25098, 0.717647, 1.0 ],
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 332.0, 275.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-2",
"outlettype" : [ "int", "bang" ],
"fontname" : "Arial"
}

}
, {
"box" : {
"maxclass" : "number",
"fontsize" : 9.0,
"numinlets" : 1,
"patching_rect" : [ 253.0, 157.0, 50.0, 17.0 ],
"numoutlets" : 2,
"id" : "obj-1",
"outlettype" : [ "int", "bang" ],
"fontname" : "Arial"
}

}
],
"lines" : [ {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-13", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-12", 0 ],
"destination" : [ "obj-11", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-12", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-1", 0 ],
"destination" : [ "obj-9", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-9", 0 ],
"destination" : [ "obj-10", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-8", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-6", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-7", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-3", 0 ],
"destination" : [ "obj-5", 0 ],
"hidden" : 0,
"midpoints" : [ 197.5, 294.0, 248.5, 294.0, 248.5, 271.0, 265.5, 271.0 ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-3", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-2", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-1", 0 ],
"destination" : [ "obj-4", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
]
}

}



Ch
September 4, 2009 | 7:02 am

Hi,

You should have a look to the "simple math" tutorial :

"left inlet triggers the calculation, the number in right inlet is stored. numbers are converted to integers before the calculation unless there as an argument with a decimal point".

Ch.

PS : you can use "copy compressed" to copy and paste patches on the forum.



Ch
September 4, 2009 | 7:11 am

Oh. sorry.
i’ve been misreading your post and patch.
you’re right, that’s weird.


September 4, 2009 | 7:35 am

math is bad at max.

-110


September 4, 2009 | 9:37 am

Thanks for the links. I couldn’t find the right search terms to find this stuff. I mainly wanted to know I’m not crazy. I knew that accuracy goes awry when dividing, but all I’m doing here is moving a decimal point.

What baffles me is that even the print object shows the result to be 1.000000. So how does 1.000000 not equal 1? Does the print object round up differently than the number box? I see what the round object does, but it seems that the float number box does the conversion correctly. I wonder what it has that other objects don’t.

I’ve worked around the problem, but I always understood that multiplying is more efficient than dividing. Am I wrong here?


September 4, 2009 | 9:45 am

There’s a very simple cure; use a float number box. You are the person who generated the number in the first place, so it is up to you to choose an appropriate method to view the result. You expected the int number box to have a specific type of behavior which it apparently doesn’t have (wrong or not).

_
johan



Zh
September 5, 2009 | 12:09 am

apparently, 100 * 0.01 is 0.9999999776483
i’ve added some larger numbers to your query patch – nothing’s solved but the error is consistent.
10000 * 0.1 =?= 99.999998
1000000 * 0.1 =?= 9999.999776
1000000000 * 0.1 = 9999999.776483

er

could this perhaps be an intel processor problem? i heard they were bad at math back in the day…

– Pasted Max Patch, click to expand. –

September 5, 2009 | 4:25 am
Quote:
What baffles me is that even the print object shows the result to be 1.000000. So how does 1.000000 not equal 1? Does the print object round up differently than the number box? I see what the round object does, but it seems that the float number box does the conversion correctly. I wonder what it has that other objects don’t.

1.000000 does not exist.

the numberbox or [i ] objects do it correct, because truncating
that what 1.000000 actually is (i think 1.000003, i have no max
here now) gives the same result than truncating and rounding would.

in other words: when [i ] receives "1.000003" it does int($f1) already, there is no need to do [round]
which does something like (int($f1-0.5))*($f1<0)+(int($f1+0.5))*($f1>=0).

roudning only starts to matter when do you not use what
i would call an "integer float" like "1.000000".
an input stream of numbers like "1.005" and "-2.007"
will drive you mad when running non-rounded into a numbox
or int object.

unfortunately both [print] and [printit] seem to output
"1.000000" for "1.000000", regardless if you have float
correction on or off in max4.

-110

.

Quote:
I’ve worked around the problem, but I always understood that multiplying is more efficient than dividing. Am I wrong here?

no that is true, and important to know for realtime stuff or signals.


September 5, 2009 | 7:10 am

I kind of follow. But I’m still not clear on why

100 / 1 = 1.00000x , which "int" truncates to 1

while

100 * .01 = 0.99999x, which "int" truncates to 0

No need to beat a dead horse here. I just started learning objective C. So I suppose I’ll learn more about digital math as I delve more into programming.

Thanks for all your input.


September 5, 2009 | 7:24 am

Int doesn’t round to the nearest whole number. It just chops off everything after the decimal.


September 5, 2009 | 8:59 am
Quote:
apparently, 100 * 0.01 is 0.9999999776483
i’ve added some larger numbers to your query patch – nothing’s solved but the error is consistent.

Ah hah. I didn’t think of trying larger numbers. At least now I can see what it thinks the answer is. And your guess about the Intel is a good one.


September 5, 2009 | 9:23 am
ksound wrote on Sat, 05 September 2009 02:59
Quote:
apparently, 100 * 0.01 is 0.9999999776483
i’ve added some larger numbers to your query patch – nothing’s solved but the error is consistent.

Ah hah. I didn’t think of trying larger numbers. At least now I can see what it thinks the answer is. And your guess about the Intel is a good one.

The issue here is about float precision (which I think has been mentioned above, but sorry I haven’t read everything in detail). Peter Castine (and others) has posted many times to the list about this (as mentioned), and it’s worth getting to know a little about this.

This is nothing to do with Intel processors. It has to do with the limitations of floating point representation. Also to correct Roman above – 1.00000 CAN be represented exactly in floating point – but 0.01 can’t. For some more info on this try here:

http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

Generally, issues with using floating point only occur in a few special cases – for conversion to int for example, where rounding may be required, depending on the application.

Regards,

Alex


September 5, 2009 | 10:05 am

The voice of the man himself.

_
johan


September 5, 2009 | 5:41 pm
Quote:
This is nothing to do with Intel processors. It has to do with the limitations of floating point representation. Also to correct Roman above – 1.00000 CAN be represented exactly in floating point – but 0.01 can’t. For some more info on this try here:

http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

Good stuff. Thanks for the wiki link.


September 5, 2009 | 5:45 pm
Quote:
The voice of the man himself.

Bingo. "expr" does the job. Check it out.

{
"patcher" : {
"fileversion" : 1,
"rect" : [ 309.0, 297.0, 869.0, 526.0 ],
"bglocked" : 0,
"defrect" : [ 309.0, 297.0, 869.0, 526.0 ],
"openrect" : [ 0.0, 0.0, 0.0, 0.0 ],
"openinpresentation" : 0,
"default_fontsize" : 9.0,
"default_fontface" : 0,
"default_fontname" : "Arial",
"gridonopen" : 0,
"gridsize" : [ 15.0, 15.0 ],
"gridsnaponopen" : 0,
"toolbarvisible" : 1,
"boxanimatetime" : 200,
"imprint" : 0,
"boxes" : [ {
"box" : {
"maxclass" : "message",
"text" : "10000",
"presentation_rect" : [ 430.0, 112.0, 0.0, 0.0 ],
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 430.0, 112.0, 36.0, 15.0 ],
"id" : "obj-19",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "print expr",
"numoutlets" : 0,
"patching_rect" : [ 626.0, 248.0, 48.0, 17.0 ],
"id" : "obj-18",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "number",
"presentation_rect" : [ 561.0, 271.0, 0.0, 0.0 ],
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 564.0, 276.0, 50.0, 17.0 ],
"id" : "obj-15",
"fontname" : "Arial",
"bordercolor" : [ 0.87451, 0.25098, 0.717647, 1.0 ],
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "expr $f1 * 0.01",
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 564.0, 206.0, 69.0, 17.0 ],
"id" : "obj-14",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "print *",
"numoutlets" : 0,
"patching_rect" : [ 478.0, 249.0, 34.0, 17.0 ],
"id" : "obj-13",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "f",
"numoutlets" : 1,
"outlettype" : [ "float" ],
"patching_rect" : [ 417.0, 254.0, 32.5, 17.0 ],
"id" : "obj-12",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "number",
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 417.0, 276.0, 50.0, 17.0 ],
"id" : "obj-11",
"fontname" : "Arial",
"bordercolor" : [ 0.87451, 0.25098, 0.717647, 1.0 ],
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "number",
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 68.0, 274.0, 50.0, 17.0 ],
"id" : "obj-10",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "/ 100",
"numoutlets" : 1,
"outlettype" : [ "int" ],
"patching_rect" : [ 68.0, 193.0, 32.5, 17.0 ],
"id" : "obj-9",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "101",
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 351.0, 112.0, 32.5, 15.0 ],
"id" : "obj-8",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "100",
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 290.0, 112.0, 32.5, 15.0 ],
"id" : "obj-7",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "message",
"text" : "99",
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 223.0, 112.0, 32.5, 15.0 ],
"id" : "obj-6",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "number",
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 256.0, 275.0, 50.0, 17.0 ],
"id" : "obj-5",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "newobj",
"text" : "* 0.01",
"numoutlets" : 1,
"outlettype" : [ "float" ],
"patching_rect" : [ 253.0, 186.0, 34.0, 17.0 ],
"id" : "obj-4",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 2
}

}
, {
"box" : {
"maxclass" : "flonum",
"numoutlets" : 2,
"outlettype" : [ "float", "bang" ],
"patching_rect" : [ 188.0, 274.0, 50.0, 17.0 ],
"id" : "obj-3",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "number",
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 332.0, 275.0, 50.0, 17.0 ],
"id" : "obj-2",
"fontname" : "Arial",
"bordercolor" : [ 0.87451, 0.25098, 0.717647, 1.0 ],
"fontsize" : 9.0,
"numinlets" : 1
}

}
, {
"box" : {
"maxclass" : "number",
"numoutlets" : 2,
"outlettype" : [ "int", "bang" ],
"patching_rect" : [ 253.0, 157.0, 50.0, 17.0 ],
"id" : "obj-1",
"fontname" : "Arial",
"fontsize" : 9.0,
"numinlets" : 1
}

}
],
"lines" : [ {
"patchline" : {
"source" : [ "obj-19", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-14", 0 ],
"destination" : [ "obj-18", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-13", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-1", 0 ],
"destination" : [ "obj-14", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-14", 0 ],
"destination" : [ "obj-15", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-1", 0 ],
"destination" : [ "obj-4", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-2", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-3", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-3", 0 ],
"destination" : [ "obj-5", 0 ],
"hidden" : 0,
"midpoints" : [ 197.5, 294.0, 248.5, 294.0, 248.5, 271.0, 265.5, 271.0 ]
}

}
, {
"patchline" : {
"source" : [ "obj-7", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-6", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-8", 0 ],
"destination" : [ "obj-1", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-9", 0 ],
"destination" : [ "obj-10", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-1", 0 ],
"destination" : [ "obj-9", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-4", 0 ],
"destination" : [ "obj-12", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
, {
"patchline" : {
"source" : [ "obj-12", 0 ],
"destination" : [ "obj-11", 0 ],
"hidden" : 0,
"midpoints" : [ ]
}

}
]
}

}


September 5, 2009 | 8:45 pm
ksound wrote on Sat, 05 September 2009 09:10
I kind of follow. But I’m still not clear on why

100 / 1 = 1.00000x , which "int" truncates to 1

while

100 * .01 = 0.99999x, which "int" truncates to 0

let me put it like this:

it is sometimes a bit more, and sometimes a bit less.

for 1.0x and 0.01x it is the comma which makes the difference.
(that is the point where alex had to correct me)

try 10 and 100 and compare it to 1.

now, back to the original "problem" and how to solve it:
with the knowledge ofthe accuracy limit, which is responsible
for 0.01 beeing 0.0099x and not 0.01x, our only option to
avoid weirdness is to take the accuracy limit into account
when coding math.

i.e., like someone suggested it above, just do everything
"math" in floating point unless you are controlling [gates]
and similar logic stuff.

and using expr will solve the cases where the order of
operands (doing three times / 0.3) matters.

-110


July 26, 2013 | 6:26 am

I haven’t tried it yet, but I believe if you split the float into two, compare the right side to .5 and if it’s greater, add one to the left side, else just the left number.


July 26, 2013 | 8:22 am

Also, please use the "copy compressed" feature so that the things you paste aren’t ginormous.

Mobile phone user’s thumbs will thank you.


July 26, 2013 | 9:03 am

welcome to the details of floating point numbers. Max is likely behaving correctly.
In short, it is unsafe to do comparisons of floating point numbers without managing the imperfection of those floating point numbers. Its just the way IEEE designed the standard. Known issue and by design. ;-)

Lots of info on this topic. Google: float comparison epsilon

http://floating-point-gui.de/errors/comparison/

http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm


July 26, 2013 | 9:41 am

why are we always reviving 5 years old threads.


July 26, 2013 | 11:31 am

because it was the time of mind revolution . all of the crucial questions has been born at that time already :)

by the way
thanks for the links


Viewing 21 posts - 1 through 21 (of 21 total)