C#浮点数越来越大

时间:2014-03-16 15:12:46

标签: c# floating-point

我试图理解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

1 个答案:

答案 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#中编写它。