首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我正在将一些C++标准函数移植到C#中进行验证(匹配结果)。

我正在将一些C++标准函数移植到C#中进行验证(匹配结果)。
EN

Code Review用户
提问于 2014-11-12 22:13:46
回答 1查看 294关注 0票数 5

您能帮我看一下下面的函数,以确保它们的行为与这些标准的C++函数(_fcvtltoaatoiCString(char*))相似吗?原因是我正在将一些代码从C++转换为C#,并且我想验证这些代码的工作原理是否完全相同。这些函数用于自定义的数字舍入过程。

代码语言:javascript
运行
复制
/// <summary>
/// C# port of C++ functions
/// </summary>
public static class LegacyEx
{
    const int _CVTBUFSIZE=50;
    /// <summary>
    /// Port of C++ _fcvt() function. See http://sydney.edu.au/engineering/it/~kev/pp/RESOURCES/cplusplus/ref/cstdlib/fcvt.html
    /// </summary>
    /// <param name="value">Floating point value to be converted to a string.</param>
    /// <param name="digits">Number of digits to be returned. If this is greater than the number of representable digits the rest of the string is padded with zeros. If this is smaller the low-order digit is rounded.</param>
    /// <param name="decimal">Pointer to an int where to store the decimal-point position respect to the beginning of the string. 0 or less indicates that the decimal point lies to the left of the digits.</param>
    /// <param name="sign">Pointer to an int that receives the sign indicator: 0 means positive sign, non-zero means negative.</param>
    /// <returns>A null-terminated buffer with the legth specified by num that contains the digits of the value.</returns>
    static char[] _fcvt(double value, int digits, out int @decimal, out int sign)
    {
        sign=value>0?0:1; // 0=positive, 1=otherwise
        char[] buffer=new char[_CVTBUFSIZE];
        value=Math.Round(Math.Abs(value),digits); //remove sign and round digits
        string t=value.ToString();
        @decimal=t.IndexOf('.')+@sign; //find index of decimal point
        t=t.Replace(".", string.Empty); //remove decimal point
        Array.Copy(t.ToCharArray(), buffer, t.Length);
        return buffer;
    }

    /// <summary>
    /// Port of C++ ltoa() function. See http://rp-www.cs.usyd.edu.au/~kev/pp/RESOURCES/cplusplus/ref/cstdlib/ltoa.html
    /// </summary>
    /// <param name="value">Value to be represented as a string.</param>
    /// <param name="buffer">Buffer where to store the resulting string.</param>
    /// <param name="radix">Numeral radix in which value has to be represented, between 2 and 36.</param>
    /// <returns> A buffer containing the string.</returns>
    static char[] ltoa(long value, ref char[] buffer, int radix)
    {
        // convert value to string of base radix
        string text=Convert.ToString(value, radix);
        // insert result into buffer
        char[] array=text.ToCharArray();
        Array.Copy(array, buffer, array.Length);
        return array;
    }

    /// <summary>
    /// Port of C++ atoi() function. See http://rp-www.cs.usyd.edu.au/~kev/pp/RESOURCES/cplusplus/ref/cstdlib/atoi.html
    /// </summary>       
    /// <param name="text">String representing an integer number.</param>
    /// <returns>The converted integer value of the input string.</returns>
    static int atoi(string text)
    {
        // get rid of whitespace
        text=text.Trim(); 
        // consider up to last digit. This will fail with "12A3" for example
        int count =text.LastIndexOfAny("0123456789".ToCharArray());
        text=text.Substring(0, count);
        int x=0;
        int.TryParse(text, out x);
        return x;
    }

    /// <summary>
    /// Port of CString(char[]) constructor
    /// </summary>
    /// <param name="buffer">A null terminated buffer for the string definition.</param>
    /// <returns>The string value from the buffer.</returns>
    static string String(char[] buffer)
    {
        int count=Array.IndexOf(buffer, '\0');
        if(count<0) { count=buffer.Length; }
        return new string(buffer, 0, count);
    }
} // LegacyEx

注意:例如,我不能直接将atoi()移植到int.Parse(),因为在我的代码中,它在某个时候被atoi(".")调用,而解析失败。另外,atoi()处理空白,而int.TryParse()不处理。

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-11-12 22:59:57

CultureInfo

由于您将浮点数字转换为字符串,因此记住点.不是唯一可能的十进制分隔符是有意义的。因此,我的建议是在每次将浮点数转换为字符串和返回时指定CultureInfo.InvariantCulture

关于_fcvt方法.

  • 您不需要首先分配buffer。我相信你根本不需要buffer
  • value=Math.Abs(value).Round(digits);不为我编译。
  • 可以使用预定义格式字符串(Fnnn,其中nnn -是十进制数),而不是舍入和转换为字符串。
  • 因为我们知道只有一个点,所以我宁愿使用String.Remove方法而不是String.Replace

我的代码:

代码语言:javascript
运行
复制
static char[] _fcvt(double value, int digits, out int @decimal, out int sign)
{
    sign = value > 0 ? 0 : 1;   // 0=positive, 1=otherwise
    string t = Math.Abs(value).ToString("F" + digits, CultureInfo.InvariantCulture);
    int dotPos = t.IndexOf('.');  //find index of decimal point
    @decimal = dotPos + sign;
    t = t.Remove(dotPos, 1);    //remove decimal point
    return t.ToCharArray();
}

关于atoi方法.

  • 您在text = text.Substring(0,count )行中出错;您应该得到1个字符: text = text.Substring(0,count+ 1);
  • 不需要Trim输入字符串。int.TryParse方法为您执行此操作。

我的代码:

代码语言:javascript
运行
复制
static int atoi(string text)
{
    // consider up to last digit. This will fail with "12A3" for example
    int count = text.LastIndexOfAny("0123456789".ToCharArray());
    text = text.Substring(0, count + 1);
    int x;
    int.TryParse(text, out x);
    return x;
}
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/69661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档