IEEE754到浮点C#
下面的代码简单地将32位整数从传递给函数的对象转换为32位整数,32位整数表示浮点数。我用在线计算器检查过,我得到的符号、指数和mantesa是正确的,但奇怪的是,我得到的答案是错误的 有人能检查一下我是否在数学上(或者可能是编程上)做得不对吗 问候IEEE754到浮点C#,c#,ieee-754,C#,Ieee 754,下面的代码简单地将32位整数从传递给函数的对象转换为32位整数,32位整数表示浮点数。我用在线计算器检查过,我得到的符号、指数和mantesa是正确的,但奇怪的是,我得到的答案是错误的 有人能检查一下我是否在数学上(或者可能是编程上)做得不对吗 问候 public double FromFloatSafe(object f) { uint fb = Convert.ToUInt32(f); uint sign, exponent = 0, mantes
public double FromFloatSafe(object f)
{
uint fb = Convert.ToUInt32(f);
uint sign, exponent = 0, mantessa = 0;
uint bias = 127;
sign = (fb >> 31) & 1;
exponent = (fb >> 23) & 0xFF;
mantessa = (fb & 0x7FFFFF);
double fSign = Math.Pow((-1), sign);
double fMantessa = 1 + (1 / mantessa);
double fExponent = Math.Pow(2, (exponent -bias));
double ret = fSign * fMantessa * fExponent;
return ret;
}
诸如此类:
uint fb = Convert.ToUInt32(f);
return BitConverter.ToSingle(BitConverter.GetBytes((int) fb), 0);
诸如此类:
uint fb = Convert.ToUInt32(f);
return BitConverter.ToSingle(BitConverter.GetBytes((int) fb), 0);
这将处理偶数非规范数:
public static float FromFloatSafe(object f)
{
uint fb = Convert.ToUInt32(f);
int sign = (int)((fb >> 31) & 1);
int exponent = (int)((fb >> 23) & 0xFF);
int mantissa = (int)(fb & 0x7FFFFF);
float fMantissa;
float fSign = sign == 0 ? 1.0f : -1.0f;
if (exponent != 0)
{
exponent -= 127;
fMantissa = 1.0f + (mantissa / (float)0x800000);
}
else
{
if (mantissa != 0)
{
// denormal
exponent -= 126;
fMantissa = 1.0f / (float)0x800000;
}
else
{
// +0 and -0 cases
fMantissa = 0;
}
}
float fExponent = (float)Math.Pow(2.0, exponent);
float ret = fSign * fMantissa * fExponent;
return ret;
}
注意,我确实认为这里有些可疑之处,但你要求的,是我写的。。。我觉得这是一个挑战
啊。。。请注意,虽然我写的东西在学术上很有趣,但我通常是这样做的:
[StructLayout(LayoutKind.Explicit)]
public struct UInt32ToFloat
{
[FieldOffset(0)]
public uint UInt32;
[FieldOffset(0)]
public float Single;
}
然后
这将处理偶数非规范数:
public static float FromFloatSafe(object f)
{
uint fb = Convert.ToUInt32(f);
int sign = (int)((fb >> 31) & 1);
int exponent = (int)((fb >> 23) & 0xFF);
int mantissa = (int)(fb & 0x7FFFFF);
float fMantissa;
float fSign = sign == 0 ? 1.0f : -1.0f;
if (exponent != 0)
{
exponent -= 127;
fMantissa = 1.0f + (mantissa / (float)0x800000);
}
else
{
if (mantissa != 0)
{
// denormal
exponent -= 126;
fMantissa = 1.0f / (float)0x800000;
}
else
{
// +0 and -0 cases
fMantissa = 0;
}
}
float fExponent = (float)Math.Pow(2.0, exponent);
float ret = fSign * fMantissa * fExponent;
return ret;
}
注意,我确实认为这里有些可疑之处,但你要求的,是我写的。。。我觉得这是一个挑战
啊。。。请注意,虽然我写的东西在学术上很有趣,但我通常是这样做的:
[StructLayout(LayoutKind.Explicit)]
public struct UInt32ToFloat
{
[FieldOffset(0)]
public uint UInt32;
[FieldOffset(0)]
public float Single;
}
然后
BitConverter.GetBytes(fb)
然后BitConverter.ToSingle()
?对fSign使用Math.Pow
有点夸张:-)符号==0?1:-1
。这是尾数,不是尾数。为什么要将浮点数作为整数传递?你到底想做什么?C#可以很好地处理强制转换,为什么使用了错误的数据类型?而且没有处理非规范数。。。如果指数=0…(双精度)fb
不工作?基于“32位整数表示浮点数”,请显示输入/输出示例。BitConverter.GetBytes(fb)
然后BitConverter.ToSingle()
?对fSign使用Math.Pow
有点夸张:-)符号==0?1:-1
。这是尾数,不是尾数。为什么要将浮点数作为整数传递?你到底想做什么?C#可以很好地处理强制转换,为什么使用了错误的数据类型?而且没有处理非规范数。。。如果指数=0…(双精度)fb
不工作?基于“32位整数表示浮点数”,请显示输入/输出示例。注意:struct
/[FieldOffset]
是一种非常好的方法(无计算)-但仅适用于具有相同位长的两种类型(在本例中,32位表示uint/float)@joe如果需要,您甚至可以使用它来分割Int64
的高/低Int32
。。。(或者是Int64
的4xInt16
)这是真的,但我的意思是将Int16
转换为double
不会以这种方式工作,因为符号。@joe这没有任何意义。。。此struct
用于进行二进制转换,而不是更改格式的强制转换。您不能使用它在int
和short
之间进行转换。。。或者将float
转换为double
。注意:struct
/[FieldOffset]
是一种非常好的方法(无需计算)-但仅适用于具有相同位长的两种类型(在本例中,uint/float为32位)@joe如果需要,您甚至可以使用它来拆分Int64
的高/低Int32
。。。(或者是Int64
的4xInt16
)这是真的,但我的意思是将Int16
转换为double
不会以这种方式工作,因为符号。@joe这没有任何意义。。。此struct
用于进行二进制转换,而不是更改格式的强制转换。您不能使用它在int
和short
之间进行转换。。。或者将浮点
转换为双精度
。谢谢,这是我一直在寻找的正确答案!谢谢,这是我一直在寻找的正确答案!