如何解决将golang float32转换为半精度floatGLSL float16作为uint16?
我需要将一些数据从Go传递到'300 es'着色器。数据由打包到uint32中的两个uint16组成。每个uint16代表一个半精度浮点数(float16)。我找到了一些看起来可以完成此工作的PD Java代码,但是我在移植最后一个语句时感到很挣扎,该语句使用了几个零扩展的右移(我认为其他的移位都很好,即非负数)。因为Go在扩展方面有点聪明,所以端口的解决方案使我望而却步。我确实认为也许第一个可以更改为左移,因为它似乎只是要定位一点以进行加法?但是最后的转变让我全神贯注:)
btw我希望我得到正确的括弧,因为Go和Java之间关于'-'和'>>'...的运算符优先级似乎有所不同。
接下来我需要走另一条路,但是如果没有右移,希望这会更容易...著名的最后一句话!
Java代码:
var mySelectedPerson = cbPeople.SelectedItem;
var name = mySelectedPerson.ToString(); // "Frank Wright"
我的部分端口:
// returns all higher 16 bits as 0 for all results
public static int fromFloat( float fval )
{
int fbits = Float.floatToIntBits( fval );
int sign = fbits >>> 16 & 0x8000; // sign only
int val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value
if( val >= 0x47800000 ) // might be or become NaN/Inf
{ // avoid Inf due to rounding
if( ( fbits & 0x7fffffff ) >= 0x47800000 )
{ // is or must become NaN/Inf
if( val < 0x7f800000 ) // was value but too large
return sign | 0x7c00; // make it +/-Inf
return sign | 0x7c00 | // remains +/-Inf or NaN
( fbits & 0x007fffff ) >>> 13; // keep NaN (and Inf) bits
}
return sign | 0x7bff; // unrounded not quite Inf
}
if( val >= 0x38800000 ) // remains normalized value
return sign | val - 0x38000000 >>> 13; // exp - 127 + 15
if( val < 0x33000000 ) // too small for subnormal
return sign; // becomes +/-0
val = ( fbits & 0x7fffffff ) >>> 23; // tmp exp for subnormal calc
return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit
+ ( 0x800000 >>> val - 102 ) // round depending on cut off
>>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0
}
我发现了看起来更高效的代码,没有分支,但是了解我的生锈(不是语言)技能之外的一些技巧;)可以移植它。
欢呼
[编辑]该代码似乎可以使用我当前使用的值(由于我没有调试着色器的经验,因此很难精确说明)。所以我想我的问题是关于端口的正确性,尤其是最后两个班次。
[Edit2]看来,我已经在一处弄错了优先顺序,并修复了上面的示例。
已更改:
func float32toUint16(f float32) uint16 {
fbits := math.Float32bits(f)
sign := uint16((fbits >> 16) & 0x00008000)
rv := (fbits & 0x7fffffff) + 0x1000
if rv >= 0x47800000 {
if (fbits & 0x7fffffff) >= 0x47800000 {
if rv < 0x7f800000 {
return sign | 0x7c00
}
return sign | 0x7c00 | uint16((fbits&0x007fffff)>>13)
}
return sign | 0x7bff
}
if rv >= 0x38800000 {
return sign | uint16((rv-0x38000000)>>13)
}
if rv < 0x33000000 {
return sign
}
rv = (fbits & 0x7fffffff) >> 23
return sign | uint16(((fbits&0x7fffff)|0x800000)+(0x800000>>(rv-102))>>(126-rv)) //these two shifts are my problem
}
func pack16(f1 float32,f2 float32) uint32 {
ui161 := float32toUint16(f1)
ui162 := float32toUint16(f2)
return ((uint32(ui161) << 16) | uint32(ui162))
}
收件人:
return sign | uint16(rv-(0x38000000>>13))
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)