为什么" dtoa.c"包含了这么多code? [英] Why does "dtoa.c" contain so much code?

查看:157
本文介绍了为什么" dtoa.c"包含了这么多code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会是第一个承认我的底层编程的总体知识是有点稀疏。我明白了许多的核心概念,但我没有定期使用它们。
话虽这么说,我是在为多少code需要 dtoa.c 绝对震惊。

I'll be the first to admit that my overall knowledge of low level programming is a bit sparse. I understand many of the core concepts but I do not use them on a regular basis. That being said I was absolutely astounded at how much code was needed for dtoa.c.

在过去的几个月我一直在C#中的ECMAScript实现,我一直在放缓在我的引擎孔填充。昨天晚上,我开始工作的 Number.prototype.toString 这是一节中的 15.7.4.2 描述http://es5.github.io/ #x15.7.4.2> ECMAScript规范 (PDF)。在第 9.8.1 ,注3提供了一个链接的 dtoa.c 的,但我一直在寻找一个挑战,所以我等着查看。以下是我想出了。

For the past couple months I have been working on an ECMAScript implementation in C# and I've been slowing filling in the holes in my engine. Last night I started working on Number.prototype.toString which is described in section 15.7.4.2 of the ECMAScript specification (pdf). In section 9.8.1, NOTE 3 offers a link to dtoa.c but I was looking for a challenge so I waited to view it. The following is what I came up with.

private IDynamic ToString(Engine engine, Args args)
{
    var thisBinding = engine.Context.ThisBinding;
    if (!(thisBinding is NumberObject) && !(thisBinding is NumberPrimitive))
    {
        throw RuntimeError.TypeError("The current 'this' must be a number or a number object.");
    }

    var num = thisBinding.ToNumberPrimitive();

    if (double.IsNaN(num))
    {
        return new StringPrimitive("NaN");
    }
    else if (double.IsPositiveInfinity(num))
    {
        return new StringPrimitive("Infinity");
    }
    else if (double.IsNegativeInfinity(num))
    {
        return new StringPrimitive("-Infinity");
    }

    var radix = !args[0].IsUndefined ? args[0].ToNumberPrimitive().Value : 10D;

    if (radix < 2D || radix > 36D)
    {
        throw RuntimeError.RangeError("The parameter [radix] must be between 2 and 36.");
    }
    else if (radix == 10D)
    {
        return num.ToStringPrimitive();
    }

    var sb = new StringBuilder();
    var isNegative = false;

    if (num < 0D)
    {
        isNegative = true;
        num = -num;
    }

    var integralPart = Math.Truncate(num);
    var decimalPart = (double)((decimal)num.Value - (decimal)integralPart);
    var radixChars = RadixMap.GetArray((int)radix);

    if (integralPart == 0D)
    {
        sb.Append('0');
    }
    else
    {
        var integralTemp = integralPart;
        while (integralTemp > 0)
        {
            sb.Append(radixChars[(int)(integralTemp % radix)]);
            integralTemp = Math.Truncate(integralTemp / radix);
        }
    }

    var count = sb.Length - 1;
    for (int i = 0; i < count; i++)
    {
        var k = count - i;
        var swap = sb[i];
        sb[i] = sb[k];
        sb[k] = swap;
    }

    if (isNegative)
    {
        sb.Insert(0, '-');
    }

    if (decimalPart == 0D)
    {
        return new StringPrimitive(sb.ToString());
    }

    var runningValue = 0D;
    var decimalIndex = 1D;
    var decimalTemp = decimalPart;

    sb.Append('.');
    while (decimalIndex < 100 && decimalPart - runningValue > 1.0e-50)
    {
        var result = decimalTemp * radix;
        var integralResult = Math.Truncate(result);
        runningValue += integralResult / Math.Pow(radix, decimalIndex++);
        decimalTemp = result - integralResult;
        sb.Append(radixChars[(int)integralResult]);
    }

    return new StringPrimitive(sb.ToString());
}

任何人都可以在低层次的编程更多的经验解释为什么的 dtoa.c 的有大约40倍之多code?我不能想象C#在于更高效。

Can anyone with more experience in low level programming explain why dtoa.c has roughly 40 times as much code? I just cannot imagine C# being that much more productive.

推荐答案

dtoa.c包含两个主要功能:DTOA(),其中转换的双串,和关于strtod(),这将字符串转换为双。它还包含了很多功能的支持,其中大部分是自行实施arbitrary- precision算术。 dtoa.c声名鹊起越来越这些转换的权利,而只能做,在一般情况下,与arbitrary- precision算术。它也有code到四种不同的舍入模式正确四舍五入的转换。

dtoa.c contains two main functions: dtoa(), which converts a double to string, and strtod(), which converts a string to a double. It also contains a lot of support functions, most of which are for its own implementation of arbitrary-precision arithmetic. dtoa.c's claim to fame is getting these conversions right, and that can only be done, in general, with arbitrary-precision arithmetic. It also has code to round conversions correctly in four different rounding modes.

您code只尝试实施DTOA(相当于),由于它采用浮点来完成其转换,不会总是让他们的权利。 (更新:请参阅我的文章<一个href=\"http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/\">http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/了解详情。)

Your code only tries to implement the equivalent of dtoa(), and since it uses floating-point to do its conversions, will not always get them right. (Update: see my article http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/ for details.)

(我已经写了很多关于这个我的博客上, http://www.exploringbinary.com/ 。六我最后的七条是大约strtod()做单独的转换阅读通过他们,看看它是如何复杂,做正确的舍入的转换。)

(I've written a lot about this on my blog, http://www.exploringbinary.com/ . Six of my last seven articles have been about strtod() conversions alone. Read through them to see how complicated it is to do correctly rounded conversions.)

这篇关于为什么&QUOT; dtoa.c&QUOT;包含了这么多code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆