Why division gives a significantly different result than multiplying by a fraction in floating points

I understand why floating point numbers cannot be compared and know about the binary representation of the mantissa and exponent, but I am not an expert, and today I came across something that I don’t get:

Namely, let's say you have something like:

float denominator, numerator, resultone, resulttwo; resultone = numerator / denominator; float buff = 1 / denominator; resulttwo = numerator * buff; 

As far as I know, different flops can give different results, and this is not unusual. But in some regional cases, these two results seem to be significantly different. To be more specific in my GLSL code calculating the Beckmann torch slope distribution for the Cook-Torrance performance model:

 float a = 1 / (facetSlopeRMS * facetSlopeRMS * pow(clampedCosHalfNormal, 4)); float b = clampedCosHalfNormal * clampedCosHalfNormal - 1.0; float c = facetSlopeRMS * facetSlopeRMS * clampedCosHalfNormal * clampedCosHalfNormal; facetSlopeDistribution = a * exp(b/c); 

gives very different results for

 float a = (facetSlopeRMS * facetSlopeRMS * pow(clampedCosHalfNormal, 4)); facetDlopeDistribution = exp(b/c) / a; 

Why? The second form of expression is problematic.

If I say, I try to add the second form of the expression to the color, I get black, although the expression should always be evaluated with a positive number. Am I getting infinity? NaN? if so, why?

+4
source share
1 answer

I have not studied your mathematics in detail, but you should know that small errors easily accumulate with all these powers and exponents. You should try and replace all var variables with var + e(var) (on paper, yes) and get an expression for a common error - without simplification between the steps, because where the error occurs!

This is also a very common problem in computational fluid dynamics, where you can observe things like “numerical diffusion” if your mesh is not aligned correctly with the simulated flow.

So, get a clear idea of ​​where the biggest mistakes came from, and if possible, rewrite the equations to minimize the numerical error.

edit: clarify example

Say you have a variable x and an expression y=exp(x) . The error in x denoted by e(x) and is small compared to x (say e(x)/x < 0.0001 , but note that this depends on the type you are using). Then you can say that

 e(y) = y(x+e(x)) - y(x) e(y) ~ dy/dx * e(x) (for small e(x)) e(y) = exp(x) * e(x) 

Thus, an increase in the absolute error exp(x) , which means that around x=0 really is no problem (not surprising, since at that moment the slope of exp(x) is equal to the value of x ), but for large x you will notice this.

The relative error will then be

 e(y)/y = e(y)/exp(x) = e(x) 

whereas the relative error in x was

 e(x)/x 

therefore, you added the coefficient x to the relative error.

+6
source

Source: https://habr.com/ru/post/1333965/


All Articles