optimization: used doubles instead of floats