How can I implement the following function in C#?
Asked
Active
Viewed 1,744 times
8
-
I suggest you familiarize yourself with System.Math.Pow - http://msdn.microsoft.com/en-us/library/system.math.pow(VS.71).aspx - this will allow you to handle both exponents and nth roots. – Steven Richards Dec 11 '09 at 23:37
-
16Building a piano, are you? – Eric Lippert Dec 12 '09 at 00:25
-
How is this a piano? Anyone care to explain pls? – Joan Venge Dec 14 '09 at 22:54
-
4The frequency of the 49th key from the left end of a piano is 440 Hz. That's the string you start tuning a piano from; you get it right, and then you tune every other string from it. The formula given is the formula for the frequency of the nth key on a piano. Incidentally, thanks for the great question Alon, I'll be writing a blog about this in January. – Eric Lippert Dec 15 '09 at 17:14
-
3And if you guys are interested in a short history and justification of the equal temperament, I wrote some blog articles about it a few years ago. http://blogs.msdn.com/ericlippert/archive/tags/Music/default.aspx – Eric Lippert Dec 15 '09 at 17:16
-
Thanks Eric. I didn't know you had a background in music :) – Joan Venge Dec 15 '09 at 20:30
-
@AlonGubkin: Here it is: http://blogs.msdn.com/b/ericlippert/archive/2010/01/07/is-there-such-a-thing-as-too-much-precision.aspx – leppie Jun 08 '13 at 10:36
4 Answers
34
double F = 440.0 * Math.Pow(2.0, (n-49.0)/12.0);

Khaled Alshaya
- 94,250
- 39
- 176
- 234
-
You are correct, the equation can be simplified to your answer, but I did a direct implementation. – Yuriy Faktorovich Dec 11 '09 at 23:44
2
440 * 12th root of 2 raised to n-49
= 440 * (2 ^ 1/12) ^(n-49)
= 440 * 2^(n/12) / 2^(49/12)
= 440 * 2^(n/12) / (2^4 * 2^1/12)
= 440 * ( 1 / 2^4 ) * 2^((n-1) /12)
= 8 * 55 * ( 1/16 ) * 2^((n-1) /12)
= 27.5 * 2^((n-1) /12)
so ....
double d = 27.5 * Math.Pow(2, (n-1) / 12.0)
And since 12th root of 2 = 1.0594630943592952645618252949463, then
double d = 27.5 * Math.Pow(1.0594630943592952645618252949463, (n-1))
so...
double d = 27.5 * Math.Pow(1.059463094359295, (n-1));

Charles Bretana
- 143,358
- 22
- 150
- 216
-
I hope that if this solution is used, a comment is placed for maintainability. – Yuriy Faktorovich Dec 12 '09 at 03:06
-
-
good catch 12th root of 2 = 1.0594630943592952645618252949463, not .083333333333333 ... I ran Windows calc badly... I have edited to correct. – Charles Bretana Dec 12 '09 at 16:11
-
You have not edited to correct the problem, which is that your method still does not give 440 when n is 49. – Eric Lippert Dec 12 '09 at 16:32
-
Thanks, I Just did... and tested it this time and now I get 440.. I unfortunately use the forum as an editor... last Error was at the end, where I made algebra error. (assumed 2^(a*b) = 2^a * 2^b, actually it's (2^a)^b ... – Charles Bretana Dec 12 '09 at 16:41
-
2Another thing. You have a 32 digit number there. Doubles are automatically rounded to around 15 digits, and the human ear cannot hear a difference between two tones that differ by so little anyway. You might want to lose about twenty of those digits: writing code that has ludicrous amounts of precision like this fools the reader into believing that such code is meaningful. – Eric Lippert Dec 12 '09 at 16:45
-
1@Eric, good point... I sort of expected the compiler to sqauwk at me if I put too many there... So when it didn't, I was too lazy to look up the limit for myself... You say it's around 15 digits ? I'll edit to that... ANd I tested with next three lower octaves of C, (n = 37, 25, and 13), and got 220, 110, and 55, respectively, so I 'spect it's right on now... – Charles Bretana Dec 12 '09 at 23:08
0
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=339638&av=501750
string funcion= "440*((2)^(1/12))^(X-49)";
X=4
double FX= GetValueFunc(4);
;) jeje

Andrew Barber
- 39,603
- 20
- 94
- 123