我试图理解C#中的浮点数学。我看了很多文件和文件在整个一天,约浮点和悲伤的大部分时间说我只有对核心问题的incling。我非常擅长英语不是母语,但有时我仍然会错过语境。从我的研究中我仍然知道的是,浮点只是4个字节的表示,因此对其进行数学运算总是错误的。您可以将epsilon与误差范围进行比较,但即便如此也只是近似值。据说要指出我所理解的是我遇到的情况。
[Test]
public void LibHfzCompressedReadTest()
{
LibHfZ lib = new LibHfZ();
HfzFile file1 = lib.loadFile("c:\\demo2_HF.hf2.gz", HfzFormat.LIBHFZ_FORMAT_HF2_GZ);
//HfzFile file2 = lib.loadFile("c:\\fractal-16bit.hf2.gz", HfzFormat.LIBHFZ_FORMAT_HF2_GZ);
List<float> data = file1.getTileData((short)0);
double HFmin = 0;
double HFmax = 0;
for(int i=0;i < data.Count;i++)
{
double f = data.ElementAt(i);
System.Console.WriteLine("float: " + f);
if(i == 0)
{
HFmin = HFmax = f;
}
else
{
if (f < HFmin && f != 0)
{
System.Console.WriteLine("new min: " + f);
HFmin = f;
}
if (f > HFmax && f != 0)
{
System.Console.WriteLine("new max: " + f);
HFmax = f;
}
}
}
System.Console.WriteLine("HFmin: " + HFmin);
System.Console.WriteLine("HFmax: " + HFmax);
float Precis = file1.header.Precis;
System.Console.WriteLine("Precis: " + Precis);
float BlockLevels = (float)((HFmax - HFmin) / Precis) + 1;
System.Console.WriteLine("BlockLevels: " + BlockLevels);
// calc scale
float VertScale = (float)(HFmax - HFmin) / BlockLevels;
if(VertScale<=0)
{
VertScale = 1.0f;
}
System.Console.WriteLine("VertScale: " + VertScale);
//System.Console.WriteLine(file2);
}
========output==========
HFmin: 0
HFmax: 1019,586
Precis: 0,01
BlockLevels: 101959,6
VertScale: 0,009999902
最终结果应该是VertScale:0,009999821 但它的VertScale:0,009999902
我确定输入数据是正确的,因为我只是从经过测试和验证的文件中读取它。我个人的预感是它与HFmax和HFmin的比较有关,可能是假阳性或阴性导致HFmax和HFmin的最终结果是错误的。
我已经经历了很多关于如何比较浮点上的平等与epsiolon的堆栈溢流,但是我没有遇到过更高或更低的问题...任何见解并请不要另一篇论文:(我今天已经阅读了几十篇文章,我只是希望理解并解决这个问题:(
UPDATE 我在VertScale上添加了一个检查&lt; = 0以查看它是否会评估并将其设置为1.0f,但输出是相同的。我尝试使用双打以及第一条评论中的推荐,但这仍然是相同的结果。
数据集:http://users.telenet.be/sunspot/hfzcsharpsource/testfloatarray.7z
答案 0 :(得分:0)
在阅读下面的文章并应用作者创建的类之后,我解决了那个更大,然后更小的困境。
http://www.codeproject.com/Articles/383871/Demystify-Csharp-floating-point-equality-and-relat
然而,现在我的平等,更小,更大的表达式起作用,但我得到的结果仍然很不理想。我决定在c ++和C#上运行相同的程序,结果如下
C++
====
Vertscale: 0.00999982096
VertOffset: 53.4127693
LineDepth: '\x2'
FirstVal: 27
Li: 14
LastVal: 41
f: 53.8227615
c#
====
VertScale: 0,009999821
VertOffset: 53,41277
LineDepth: 2
FirstVal: 27
Li: 14
LastVal: 41
f: 53,82276
您会注意到计算后VertScale和f值的微小差异。您会认为它们无关紧要,但是这些小改动使我无法将文件写入磁盘,因为它会破坏我试图编写的压缩算法。
http://www.bundysoft.com/docs/doku.php?id=l3dt:formats:specs:hf2
我不得不面对这样一个事实:由于浮点计算在c#中的结果不同而c ++文件的原始设计者编写了他的算法,因此不可能在C#中编写它。