mirror of
https://github.com/mborgerding/kissfft.git
synced 2026-10-28 18:48:53 -04:00
Fix infinite loop in kiss_fft_next_fast_size for n<=0 (issue #121)
kiss_fft_next_fast_size(0) never terminated because the factorization loop divides m by 2/3/5 forever when m stays 0. Per maintainer decision, return 1 for n<=0. Add regression test next_fast_size covering n=0, n<0 and positive inputs.
This commit is contained in:
@@ -411,6 +411,8 @@ void kiss_fft_cleanup(void)
|
|||||||
|
|
||||||
int kiss_fft_next_fast_size(int n)
|
int kiss_fft_next_fast_size(int n)
|
||||||
{
|
{
|
||||||
|
if (n <= 0) /* nothing to factor; avoid infinite loop for n<=0 */
|
||||||
|
return 1;
|
||||||
while(1) {
|
while(1) {
|
||||||
int m=n;
|
int m=n;
|
||||||
while ( (m%2) == 0 ) m/=2;
|
while ( (m%2) == 0 ) m/=2;
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ target_compile_definitions(tkfc PRIVATE KFC_TEST)
|
|||||||
add_kissfft_test_executable(ffr twotonetest.c)
|
add_kissfft_test_executable(ffr twotonetest.c)
|
||||||
add_kissfft_test_executable(tr test_real.c)
|
add_kissfft_test_executable(tr test_real.c)
|
||||||
|
|
||||||
|
add_kissfft_test_executable(next_fast_size next_fast_size.c)
|
||||||
|
|
||||||
add_kissfft_test_executable(testcpp testcpp.cc)
|
add_kissfft_test_executable(testcpp testcpp.cc)
|
||||||
|
|
||||||
if(KISSFFT_DATATYPE MATCHES "^simd$")
|
if(KISSFFT_DATATYPE MATCHES "^simd$")
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
|
||||||
|
* This file is part of KISS FFT - https://github.com/mborgerding/kissfft
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
* See COPYING file for more information.
|
||||||
|
*
|
||||||
|
* Regression test for github issue #121: kiss_fft_next_fast_size(0)
|
||||||
|
* used to hang forever in the factorization loop.
|
||||||
|
*/
|
||||||
|
#include "kiss_fft.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
/* n<=0 must return 1 per maintainer decision, not hang */
|
||||||
|
if (kiss_fft_next_fast_size(0) != 1) {
|
||||||
|
fprintf(stderr, "FAIL: kiss_fft_next_fast_size(0) != 1\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (kiss_fft_next_fast_size(-3) != 1) {
|
||||||
|
fprintf(stderr, "FAIL: kiss_fft_next_fast_size(-3) != 1\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* positive inputs keep their pre-fix behavior */
|
||||||
|
{
|
||||||
|
int expected[9] = { 0, 1, 2, 3, 4, 5, 6, 8, 8 };
|
||||||
|
for (n = 1; n <= 8; ++n) {
|
||||||
|
if (kiss_fft_next_fast_size(n) != expected[n]) {
|
||||||
|
fprintf(stderr, "FAIL: kiss_fft_next_fast_size(%d) = %d, expected %d\n",
|
||||||
|
n, kiss_fft_next_fast_size(n), expected[n]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("kiss_fft_next_fast_size: all checks passed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user