开发者

Why does division yield a vastly different result than multiplication by a fraction in floating points

开发者 https://www.devze.com 2023-02-02 05:20 出处:网络
I understand why floating point numbers can\'t be compared, and know about the mantissa and exponent binary representation, but I\'m no expert and today I came across something I don\'t get:

I understand why floating point numbers can't be compared, and know about the mantissa and exponent binary representation, but I'm no expert and today I came across something I don't get:

Namely lets say you have something like:

float denominator, numerator, resultone, resulttwo;

resultone = numerator / denominator;

float开发者_运维百科 buff = 1 / denominator;

resulttwo = numerator * buff;

To my knowledge different flops can yield different results and this is not unusual. But in some edge cases these two results seem to be vastly different. To be more specific in my GLSL code calculating the Beckmann facet slope distribution for the Cook-Torrance lighitng 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);

yields very very different results to

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

Why does it? The second form of the expression is problematic.

If I say try to add the second form of the expression to a color I get blacks, even though the expression should always evaluate to a positive number. Am I getting an infinity? A NaN? if so why?


I didn't go through your mathematics in detail, but you must be aware that small errors get pumped up easily by all these powers and exponentials. You should try and substitute all variables var with var + e(var) (on paper, yes) and derive an expression for the total error - without simplifying in between steps, because that's where the error comes from!

This is also a very common problem in computational fluid dynamics, where you can observe things like 'numeric diffusion' if your grid isn't properly aligned with the simulated flow.

So get a clear grip on where the biggest errors come from, and rewrite equations where possible to minimize the numeric error.

edit: to clarify, an example

Say you have some variable x and an expression y=exp(x). The error in x is denoted 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 could 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)

So there's a magnification of the absolute error of exp(x), meaning that around x=0 there's really no issue (not a surprise, since at that point the slope of exp(x) equals that of x) , but for big x you will notice this.

The relative error would then be

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

whilst the relative error in x was

e(x)/x

so you added a factor of x to the relative error.

0

精彩评论

暂无评论...
验证码 换一张
取 消