c# - Converting float to UInt32 - which expression is more precise -
i have number float x should in <0,1> range undergo several numerical operations - result may outside <0,1>.
i need convert result uint y using entire range of uint32. of course, need clamp x in <0,1> range , scale it.
but order of operations better?
y = (uint)round(min(max(x, 0.0f), 1.0f) * uint32.maxvalue) or
y = (uint)round(min(max(x * uint32.maxvalue, 0.0f), uint32.maxvalue) in words, improve scale first, clamp or clamp , scale? not profound in ieee floating point representation, believe there difference in order of computation of above expressions.
because multiplication [0.0f .. 1.0f] [0 .. uint32.maxvalue] can approximative, order of operations has property want multiply, clamp, round.
the maximum value clamp float below 232, is, 4294967040.0f. although number several units below uint32.maxvalue, allowing larger value mean overflowing conversion uint32.
either of lines below should work:
y = (uint)round(min(max(x * 4294967040.0f, 0.0f), 4294967040.0f)) in first version, have alternative multiply uint32.maxvalue instead. selection between having larger results overall (and rounding 4294967040 few more values close 1.0f below it), or sending 4294967040 values 1.0f , above.
you can clamp [0.0f .. 1.0f] if not multiply big number afterwards, there no risk of making value larger largest float can converted:
y = (uint)round(min(max(x, 0.0f), 1.0f) * 4294967040.0f) suggestion comment below, crafting conversion goes uint32.maxvalue:
if (x <= 0.0f) y = 0 else if (x < 0.5f) y = (uint) round (x * 4294967296.0f) else if (x >= 1.0f) y = uint32.maxvalue else y = uint32.maxvalue - (uint) round ((1.0f - x) * 4294967296.0f) this computation considered function x y increasing (including around 0.5f) , goes uint32.maxvalue. can re-order tests according think distribution of values. in particular, assuming few values below 0.0f or above 1.0f, can compare 0.5f first, , compare bound relevant:
if (x < 0.5f) { if (x <= 0.0f) y = ... else y = ... } else { if (x >= 1.0f) y = ... else y = ... } c# floating-point floating-point-precision numerical-stability
No comments:
Post a Comment