8

How can I implement the following function in C#?

alt text

Community
  • 1
  • 1
Alon Gubkin
  • 56,458
  • 54
  • 195
  • 288
  • 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
  • 16
    Building 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
  • 4
    The 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
  • 3
    And 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 Answers4

34
double F = 440.0 * Math.Pow(2.0, (n-49.0)/12.0);
Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
13
440 * Math.Pow(Math.Pow(2, 1.0/12), n - 49)
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
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
  • You sure that math is right? Try n = 49. You should get 440. – Eric Lippert Dec 12 '09 at 05:27
  • 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
  • 2
    Another 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