nayuki / Nayuki-web-published-code

Complete collection of code files (*.java/js/py/cpp/etc.) published on Project Nayuki website.

Home Page:https://www.nayuki.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect argument checks in FastDct.ts

Smilebags opened this issue · comments

Hi, after reviewing FastDct.ts, I noticed a few incorrect and redundant argument checks, notably the check for length === power of two in fastDctLee.transform and fastDctLee.inverseTransform.

The expression (n <= 0 && (n & (n - 1)) != 0) will return true for all negative numbers (which will never be the result of Array.length. No check for n <= 0 is needed, so the correct check should be:

if((n & (n - 1)) !== 0) throw "Length must be a power of 2";

In the current state, the code runs even with invalid input but with incorrect results due to the improper logic in the check.

Wow, what was I thinking?! Thanks for pointing this out. Now I realize that I wrote && instead of ||.

I still need to exclude length 0 because it's not a power of 2 and the Lee Fast DCT doesn't handle that case. As for checking n <= 0 instead of n == 0, it's to be extra defensive in languages like C# that have signed integer types.

I made the fixes now, to all affected languages: 3bf2d8f

I just want to double-check, does the new logic look correct to you now?

Yes, I think the new logic looks correct. On another note, what mandates the power of 2 length? There doesn't seem to be anything in the math that needs a power of 2 length. I'm guessing it has something to do with particular cases which can be precomputed/shortcuts can be made if the length is a power of 2?

The Lee fast DCT does some work on the input array, then divides it in half, recurses on each half, and recombines them. If the original length is a power of 2, then we can recurse all the way down to a base case of length 1, instead of some other odd length.

Right, interesting. Anyway, I believe this issue is fixed now. Thanks :)