2013-04-24 7 views
1

Я пытаюсь сделать фильтрацию .wav значение выборки данных с использованием формулы Хаара, но получил ошибку «плавающей точкой» переполнениеКак справиться с переполнением с плавающей запятой?

Отредактировано: добавить дополнительный код

numsamples := round(wavehdr.SampleRate); 
SetLength(wavedata[0].Data, numsamples); 
Stream.Read(wavedata[0].Data[0], numsamples); 
SetLength(cA1, numsamples); 
SetLength(cD1, numsamples); 
for i:=1 to numsamples-1 do begin 
cA1[i]:=(wavedata[0].Data[(i*2)-1]*0.7071) + (wavedata[0].Data[(i*2)]*0.7071); 
cD1[i]:=(wavedata[0].Data[(i*2)-1]*0.7071) + (wavedata[0].Data[(i*2)]*-0.7071); 
end; 

где wavedata [0] .data [ i], я получаю его из функции Stream.Read, чтобы загрузить пример данных. WAV-файла. Я не знаю, почему я получил ошибку или что означает ошибка, и я искал ошибку, в основном вызванную divizion на ноль, но в моем коде нет divizion на ноль. Так что, может быть, я могу помочь здесь, что означает ошибка в моем коде?

EDIT 1: (я действительно новичок в Дельфы, этот код не мой я нашел это интернет в моем понимании следующего кода является один для чтения .wav значения данных файла образец.)

type 
    TWaveHeader = packed record 

    Marker_RIFF: array [0..3] of char; 
    ChunkSize: cardinal; 


    Marker_WAVE: array [0..3] of char; 


    Marker_fmt: array [0..3] of char; 
    SubChunkSize: cardinal; 


    FormatTag: word; 

    { nChannels : 1 mono, 2 stereo } 
    NumChannels: word; 
    SampleRate: longint; 
    BytesPerSecond: longint; 
    BytesPerSample: word; 
    BitsPerSample: word; 


    Marker_data: array [0..3] of char; 


    DataBytes: longint; 
    end; 

    TChannel = record 

    Data : array of double; 
    end; 

И частная декларация:

private 
    wavehdr:TWaveHeader; 

функция:

FillChar(wavehdr, sizeof(wavehdr),0); 
Stream.Read(wavehdr,sizeof(wavehdr)); 

я изменил немного из код для обработки нулевого значения при чтении данных выборки:

if(IsNan(wavedata[0].Data[(i*2)-1])) then begin 
     wavedata[0].Data[(i*2)-1]:=0; 
    end 
    else if(IsNan(wavedata[0].Data[(i*2)])) then begin 
     wavedata[0].Data[(i*2)]:=0; 
    end; 
+0

how являются cA1, cD1 и wavedata [0]. Объявлены данные? –

+0

cA1 cD1 и wavedata были все массивом double. который может содержать значение, например: 0, 1.98E-04 и т. д. (это значение выборки .wav-данных). –

+0

результат - большой, чтобы его можно было хранить в вашем поплавке, чтобы понять, использует Math; процедура TForm6.Button1Click (отправитель: TObject); var f: Double; начало f: = MaxDouble; f: = F * 2; Showmessage (FloatToStr (F)) end; – bummi

ответ

6

для i:=0 ...

(wavedata[0].Data[(i*2)-1]

У вас действительно есть элемент массива Data[-1]?

P.S. Установите параметр компилятора проверки диапазона при отладке.

Edit: я вижу какой-то новый код, так что давайте идти с шагом 2:

SetLength(wavedata[0].Data, **numsamples**); 

for i:=1 to **numsamples**-1 

wavedata[0].Data[(**i*2)**] 

ли мы тщательно проверить каждую строку кода?

+0

Это очень вероятное объяснение. +1 –

+0

@DavidHeffernan Странно, как мне кажется, я видел (и имел личный вызов для отладки) большие кодовые базы, где некоторые массивы начинались с 0, некоторые на 1, некоторые на -1, некоторые на -2 и т. Д. то же самое, что это вероятное объяснение. –

+0

Да, извините, что это тоже была ошибка, но после того, как я изменил для i: = 0 на i: = 1, я все равно получаю ту же ошибку. –

4

Переполнения возникает, когда выражение дает значение, которое не вписывается в диапазоне от типа данных, в котором вычисляется выражение. Переполнение может происходить для положительных и отрицательных чисел.

Ваше конкретное выражение приведет только к переполнению, если входные значения уже близки к переполнению значения с плавающей запятой. Итак, если вы используете значения двойной точности, например, ваш код может переполняться только в том случае, если входные данные имеют величину около 1e308.

Кажется маловероятным, что ваши входные данные действительно имеют такую ​​форму. Поэтому я предполагаю, что ваша проблема связана с тем, как вы читаете свои входные данные. Я подозреваю, что вы читаете его неправильно и так заканчиваете выполнение арифметики по бессмысленным значениям.

+0

Это хорошее объяснение для начинающих, таких как я: D. да, я получил некоторую ценность, которая, по моему мнению, превосходит диапазон диапазонов данных: 1.39073482014559E-309, 4.24399158143648E-314 и т. д. Я прочитал свои входные данные, используя код, который я нашел, возможно, я отредактирую и опубликую его, чтобы вы могли их видеть. –

+0

У меня есть сообщение больше, чтобы добавить деталь, как я прочитал значение .wav, может быть, вы можете исправить меня, если я делаю это неправильно? –

+0

Думаю, я ответил на исходный вопрос, который вы задали. Это было довольно общим по своей природе. Я не в состоянии подробно отладить особенности вашего кода. Я уверен, что ваши входные данные читаются неправильно. –

0

После того, как я попробую это, я выяснил свои собственные ошибки, благодаря @MBo ваш ответ, сужающий mw focus в цикле, это действительно глупо от меня.Сквозными должен быть как

for i:=0 to round(numsamples/2) do begin 

это не элемент данных [-1], что проблема, но, если длина массива wavedata = X, то я попытаться достичь элемент [Х * 2], которые не являются доступный, это, несомненно, после половины приведет к ошибке. например массив [4], но я пытаюсь достичь массива [4 * 2], который недоступен (извините за мой плохой английский, я не знаю, было ли мое объяснение хорошим или нет), но спасибо всем за помощь: D

+0

Это ничего не добавляет к ответу MBo. Вы должны принять этот ответ и удалить его. –

Смежные вопросы