GLSL pow() function question

Hi everyone,

I’m quite new to GLSL so I don’t know how basic/stupid this question might be:

As I was trying some of the native GLSL functions, I run into what to me seems like a mathematical inconsistency (see the code example below). To be more precise, I’m getting two different results when using the pow() function vs “manually” multiplying the same value. Does this make sense to anyone, or am I missing something?

Thanks in advance,

B

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;

void main(){
    vec2 vUV = gl_FragCoord.xy / u_resolution;
    vUV -= 0.5;
    vUV *= 5.0;
    float y = vUV.y;
    vec3 color = vec3(pow(y, 3.0)); // w/ pow()
    // color = vec3(y*y*y); // w/out pow()
    gl_FragColor = vec4(color, 1.0);
}

How different? To the level of floating-point rounding error, or something more substantial?

Note that pow(x,y) is undefined if x<0. Mathematically, powers of negative numbers are only real if the exponent is rational and has an odd denominator (which includes integers). But pow() typically doesn’t provide special treatment for integer exponents. In particular, it may be implemented as exp(y*log(x)), and log(x) is undefined for x<=0. Even for positive values, log(x) typically won’t be exactly representable as a floating-point value even if x and x*x*x are (in fact, it’s guaranteed not to be exact for any floating-point value other than log(1)=0). So exp(y*log(x)) will introduce at least two rounding errors even if log() and exp() are correct to within the precision of floating-point (and they may be less accurate).

Thanks! That does explain the problem I was encountering — great to know!

Best,

B