我正在以编程方式计算给定音符的频率。
快速介绍:
- 音符A4的频率为440Hz
- 高一个八度的音符是低八度中相同音符的频率的两倍(所以A3是 220Hz,A2是 110Hz)
- 一个音符与下一个半音之间的差异是对数 2 到 12 分之一。
C3 = B3 x 2 ^ (1/12)
用 Ruby 编写这个公式,我想出了以下内容:
# Starting from the note A4 (440Hz)
A4 = 440.to_f
# I want the frequencies of each note over the next 3 octaves
number_of_octaves = 3
# There are 12 semitones per octave
SEMITIONES_PER_OCTAVE = 12
current_freq = A4
(number_of_octaves * SEMITIONES_PER_OCTAVE).times do |i|
puts "-----" if i % 12 == 0 # separate each octave with dashes
puts current_freq
current_freq = current_freq * 2 ** Rational('1/12')
end
我得到的结果并不完美。A 音符的四舍五入似乎比预期的要高一点:
-----
440.0
466.1637615180899
493.8833012561241
523.2511306011974
554.3652619537443
587.3295358348153
622.253967444162
659.2551138257401
698.456462866008
739.988845423269
783.9908719634989
830.6093951598906
-----
880.0000000000003
932.3275230361802
987.7666025122486
1046.502261202395
1108.7305239074888
1174.6590716696307
1244.5079348883241
1318.5102276514804
1396.9129257320162
1479.9776908465383
1567.981743926998
1661.2187903197814
-----
1760.000000000001
1864.6550460723606
1975.5332050244976
2093.0045224047904
2217.4610478149784
2349.3181433392624
2489.0158697766497
2637.020455302962
2793.825851464034
2959.9553816930784
3135.963487853998
3322.4375806395647
请注意 A 频率 - 不是 880、1760,而是略高一些。
我认为 Ruby 的Rational应该提供准确的计算并避免使用浮点数造成的舍入错误。
谁能解释一下:
- 为什么这个结果不准确?
- 如何改进上述代码以获得真正准确的结果?