program ex28;
const lowestnote = 27.5;
keyboard_length = 88;
semitone = 1.05946;
var frequency : double;
note : integer;
x : char;
begin
frequency := lowestnote;
for note := 1 to keyboard_length do
begin
writeln ('frequency');
frequency := frequency * semitone;
end;
readln (x);
end.
This does not give the best answers, no matter how large we make the type of real number. Each time we multiply by semitone we introduce inaccuracy into the result, compounded 88 times, the number of times the loop executes. The frequency of a number can be represented by lowestnote * 2 ^ (note/12). Now a ^ x = e ^ (x ln(a)), or frequency = lowestnote * exp (note * ln (2) / 12). Rather than plug this directly into the for loop above it is better to work out some of it before the loop begins so as to perform the calculation once rather than 88 times. The lowest note now corresponds to the value note = 0 because exp (0) =1, so we change the bounds of the for loop to 0 to keyboard_length -1. Thus:
program ex26a;
const lowestnote = 27.5;
keyboard_length = 88;
var frequency, ratio : double;
note : integer;
x : char;
begin
ratio := ln (2) / 12;
for note := 0 to keyboard_length - 1 do
begin
frequency := lowestnote * exp (ratio *
note);
writeln ('frequency is', frequency );
end;
readln (x);
end.
(Example taken from Programming in Pascal by Peter Grogono)