HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

I am porting some C++ standard functions into C# for verification (matching results)

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
portingintostandardsomeforresultsfunctionsmatchingverification

Problem

Can you help me look through the functions below to make sure they behave similarly as these standard C++ functions (_fcvt, ltoa, atoi, CString(char*)). The reason is that I am converting some code from C++ to C# and I want to validate that the code works EXACTLY the same. These functions are used in a custom numeric rounding procedure I am looking at.

```
///
/// C# port of C++ functions
///
public static class LegacyEx
{
const int _CVTBUFSIZE=50;
///
/// Port of C++ _fcvt() function. See http://sydney.edu.au/engineering/it/~kev/pp/RESOURCES/cplusplus/ref/cstdlib/fcvt.html
///
/// Floating point value to be converted to a string.
/// 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.
/// 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.
/// Pointer to an int that receives the sign indicator: 0 means positive sign, non-zero means negative.
/// A null-terminated buffer with the legth specified by num that contains the digits of the value.
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;
}

///
/// Port of C++ ltoa() function. See http://rp-www.cs.usyd.edu.au/~kev/pp/RESOURCES/cplusplus/ref/cstdlib/ltoa.html
///
/// Value to be represented as a string.
/// Buffer where to store t

Solution

CultureInfo

Since you convert floating-point numbers to strings, it makes sense to keep in mind that the dot . is not the only possible decimal separator. Therefore my advice is to specify the CultureInfo.InvariantCulture each time when converting a floating-point number to string and back.

About the _fcvt method.

  • You don't need to allocate a buffer first. And I believe you don't need the buffer at all.



  • The value=Math.Abs(value).Round(digits); doesn't compile for me.



  • Instead of the rounding and converting to string, you could use predefined format string (Fnnn, where nnn - is the number of decimal digits)



  • Since we know that there is only 1 dot, I'd prefer to use the String.Remove method instead of the String.Replace.



My code:

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();
}


About the atoi method.

-
You have mistake in the line

text = text.Substring(0, count);


You should get 1 more char:

text = text.Substring(0, count + 1);


  • There is no need to Trim the input string. The int.TryParse method do it for you.



My code:

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;
}

Code Snippets

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();
}
text = text.Substring(0, count);
text = text.Substring(0, count + 1);
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;
}

Context

StackExchange Code Review Q#69661, answer score: 5

Revisions (0)

No revisions yet.