Skip to content

Commit

Permalink
Merge pull request #85 from epam/issue84-to-string-as-double
Browse files Browse the repository at this point in the history
Java: Format string in the same way as Double.toString()
  • Loading branch information
agdavydov81 authored Sep 22, 2023
2 parents 1930b48 + 8e98165 commit 502cbd7
Show file tree
Hide file tree
Showing 14 changed files with 729 additions and 336 deletions.
18 changes: 9 additions & 9 deletions csharp/EPAM.Deltix.DFP.Test/Decimal64Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ public void TestParseReImpl()
{
var testStr = "000";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.Zero, value);
Expand All @@ -716,7 +716,7 @@ public void TestParseReImpl()
{
var testStr = "00..";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.NaN, value);
Expand All @@ -726,7 +726,7 @@ public void TestParseReImpl()
{
var testStr = "000235";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.FromInt(235), value);
Expand All @@ -736,7 +736,7 @@ public void TestParseReImpl()
{
var testStr = "00.0000235";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.FromFixedPoint(235, 7), value);
Expand All @@ -746,7 +746,7 @@ public void TestParseReImpl()
{
var testStr = "1234512345123451234500000";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.FromFixedPoint(1234512345123451, -9), value);
Expand All @@ -756,7 +756,7 @@ public void TestParseReImpl()
{
var testStr = "1234512345123451234500000e+12345123451234512345";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.PositiveInfinity, value);
Expand All @@ -766,7 +766,7 @@ public void TestParseReImpl()
{
var testStr = "-5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.NegativeInfinity, value);
Expand All @@ -776,7 +776,7 @@ public void TestParseReImpl()
{
var testStr = "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.Zero, value);
Expand All @@ -786,7 +786,7 @@ public void TestParseReImpl()
{
var testStr = "123 x99";
uint fpsf;
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, out fpsf, roundMode));
var value = Decimal64.FromUnderlying(DotNetReImpl.bid64_from_string(testStr, Decimal64.DecimalMarkAny, out fpsf, roundMode));
double doubleValue;
var doubleParseOk = Double.TryParse(testStr, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue);
Assert.AreEqual(Decimal64.NaN, value);
Expand Down
71 changes: 64 additions & 7 deletions csharp/EPAM.Deltix.DFP/Decimal64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public struct Decimal64 : IComparable<Decimal64>, IEquatable<Decimal64>, ISerial
public static readonly int MaxExponent = 384;
public static readonly int MinExponent = -383;

public const char DecimalMarkDot = '.';
public const char DecimalMarkComma = ',';
public const char DecimalMarkDefault = DecimalMarkDot;
public static string DecimalMarkAny = "" + DecimalMarkDot + DecimalMarkComma;

#endregion

public UInt64 Bits { get; }
Expand All @@ -53,7 +58,12 @@ internal Decimal64(UInt64 value)

public override String ToString()
{
return DotNetImpl.ToString(Bits);
return DotNetImpl.ToString(Bits, DecimalMarkDefault);
}

public String ToString(char decimalMark)
{
return DotNetImpl.ToString(Bits, decimalMark);
//return ((Double)this).ToString(CultureInfo.InvariantCulture);
}

Expand Down Expand Up @@ -942,7 +952,18 @@ public Decimal64 Canonize()
public static Decimal64 Parse(String text)
{
uint fpsf;
var ret = DotNetReImpl.bid64_from_string(text, out fpsf);
var ret = DotNetReImpl.bid64_from_string(text, DecimalMarkAny, out fpsf);
if ((fpsf & DotNetReImpl.BID_INVALID_FORMAT) != 0)
throw new FormatException("Input string is not in a correct format.");
//else if ((fpsf & DotNetReImpl.BID_INEXACT_EXCEPTION) != 0)
// throw new FormatException("Can't convert input string to value without precision loss.");
return FromUnderlying(ret);
}

public static Decimal64 Parse(String text, String decimalMarks)
{
uint fpsf;
var ret = DotNetReImpl.bid64_from_string(text, decimalMarks, out fpsf);
if ((fpsf & DotNetReImpl.BID_INVALID_FORMAT) != 0)
throw new FormatException("Input string is not in a correct format.");
//else if ((fpsf & DotNetReImpl.BID_INEXACT_EXCEPTION) != 0)
Expand All @@ -966,15 +987,36 @@ public enum StatusValue
public static Boolean TryParse(String text, out Decimal64 result, out StatusValue status)
{
uint fpsf;
result = FromUnderlying(DotNetReImpl.bid64_from_string(text, out fpsf));
result = FromUnderlying(DotNetReImpl.bid64_from_string(text, DecimalMarkAny, out fpsf));
status = (StatusValue)fpsf;
return status == StatusValue.Exact;
}

public static Boolean TryParse(String text, String decimalMarks, out Decimal64 result, out StatusValue status)
{
uint fpsf;
result = FromUnderlying(DotNetReImpl.bid64_from_string(text, decimalMarks, out fpsf));
status = (StatusValue)fpsf;
return status == StatusValue.Exact;
}

public static Boolean TryParse(String text, out Decimal64 result)
{
uint fpsf;
var ret = DotNetReImpl.bid64_from_string(text, out fpsf);
var ret = DotNetReImpl.bid64_from_string(text, DecimalMarkAny, out fpsf);
if ((fpsf & DotNetReImpl.BID_INVALID_FORMAT) != 0)
{
result = NaN;
return false;
}
result = FromUnderlying(ret);
return true;
}

public static Boolean TryParse(String text, String decimalMarks, out Decimal64 result)
{
uint fpsf;
var ret = DotNetReImpl.bid64_from_string(text, decimalMarks, out fpsf);
if ((fpsf & DotNetReImpl.BID_INVALID_FORMAT) != 0)
{
result = NaN;
Expand All @@ -986,17 +1028,32 @@ public static Boolean TryParse(String text, out Decimal64 result)

public String ToScientificString()
{
return DotNetImpl.ToScientificString(Bits);
return DotNetImpl.ToScientificString(Bits, DecimalMarkDefault);
}

public String ToScientificString(char decimalMark)
{
return DotNetImpl.ToScientificString(Bits, decimalMark);
}

public StringBuilder AppendTo(StringBuilder text)
{
return DotNetImpl.AppendTo(Bits, text);
return DotNetImpl.AppendTo(Bits, DecimalMarkDefault, text);
}

public StringBuilder AppendTo(char decimalMark, StringBuilder text)
{
return DotNetImpl.AppendTo(Bits, decimalMark, text);
}

public StringBuilder ScientificAppendTo(StringBuilder text)
{
return DotNetImpl.ScientificAppendTo(Bits, text);
return DotNetImpl.ScientificAppendTo(Bits, DecimalMarkDefault, text);
}

public StringBuilder ScientificAppendTo(char decimalMark, StringBuilder text)
{
return DotNetImpl.ScientificAppendTo(Bits, decimalMark, text);
}

#endregion
Expand Down
30 changes: 15 additions & 15 deletions csharp/EPAM.Deltix.DFP/DotNetImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ public static UInt64 FromDecimal(Decimal dec)
{
DecimalNet* decPtr = (DecimalNet*)&dec;
ulong sign = ((ulong)decPtr->flags & 0x80000000UL) << 32;
int exp = -((int)(decPtr ->flags >> 16) & 0xFF);
int exp = -((int)(decPtr->flags >> 16) & 0xFF);
ulong mantissa;
if (decPtr->hi == 0)
{
Expand Down Expand Up @@ -1158,7 +1158,7 @@ static bool IsRoundedToReciprocalImpl(int addExponent, Pair96 coefficientMulR, F
#endregion
#region Formatting & Parsing

public static String ToString(UInt64 value)
public static String ToString(UInt64 value, char decimalMark)
{
if (!IsFinite(value))
{
Expand Down Expand Up @@ -1234,7 +1234,7 @@ public static String ToString(UInt64 value)
{
Int64 old = coefficient + '0';
coefficient /= 10;
*p = '.';
*p = decimalMark;
p += 0 == dotPos-- ? -1 : 0; // Hopefully branch-free method to insert decimal dot
*p-- = (char)(old - coefficient * 10); // = [old - new * 10]
} while (coefficient != 0);
Expand All @@ -1243,7 +1243,7 @@ public static String ToString(UInt64 value)
{
for (; dotPos > 0; --dotPos)
*p-- = '0';
p[0] = '.';
p[0] = decimalMark;
p[-1] = '0';
p -= 2;
}
Expand All @@ -1256,7 +1256,7 @@ public static String ToString(UInt64 value)
if ('0' == *e)
{
while ('0' == *--e) { }
if ('.' == *e)
if (decimalMark == *e)
--e;
}
}
Expand All @@ -1267,7 +1267,7 @@ public static String ToString(UInt64 value)
}
}

public static string ToScientificString(UInt64 value)
public static string ToScientificString(UInt64 value, char decimalMark)
{
if (IsNull(value))
return "null";
Expand All @@ -1285,7 +1285,7 @@ public static string ToScientificString(UInt64 value)
UInt64 coefficient = Unpack(value, out sign, out exponent);

if (coefficient == 0)
return "0.000000000000000e+000";
return "0" + decimalMark + "000000000000000e+000";

exponent -= BaseExponent;

Expand All @@ -1308,7 +1308,7 @@ public static string ToScientificString(UInt64 value)

bi--;
*bi = *(bi + 1);
*(bi + 1) = '.';
*(bi + 1) = decimalMark;

if (sign)
*--bi = '-';
Expand All @@ -1329,7 +1329,7 @@ public static string ToScientificString(UInt64 value)
}
}

public static StringBuilder AppendTo(UInt64 value, StringBuilder text)
public static StringBuilder AppendTo(UInt64 value, char decimalMark, StringBuilder text)
{
if (!IsFinite(value))
{
Expand Down Expand Up @@ -1411,7 +1411,7 @@ public static StringBuilder AppendTo(UInt64 value, StringBuilder text)
{
Int64 old = coefficient + '0';
coefficient /= 10;
*p = '.';
*p = decimalMark;
p += 0 == dotPos-- ? -1 : 0; // Hopefully branch-free method to insert decimal dot
*p-- = (char)(old - coefficient * 10); // = [old - new * 10]
} while (coefficient != 0);
Expand All @@ -1420,7 +1420,7 @@ public static StringBuilder AppendTo(UInt64 value, StringBuilder text)
{
for (; dotPos > 0; --dotPos)
*p-- = '0';
p[0] = '.';
p[0] = decimalMark;
p[-1] = '0';
p -= 2;
}
Expand All @@ -1433,7 +1433,7 @@ public static StringBuilder AppendTo(UInt64 value, StringBuilder text)
if ('0' == *e)
{
while ('0' == *--e) { }
if ('.' == *e)
if (decimalMark == *e)
--e;
}
}
Expand All @@ -1450,7 +1450,7 @@ public static StringBuilder AppendTo(UInt64 value, StringBuilder text)
}
}

public static StringBuilder ScientificAppendTo(UInt64 value, StringBuilder text)
public static StringBuilder ScientificAppendTo(UInt64 value, char decimalMark, StringBuilder text)
{
if (IsNull(value))
return text.Append("null");
Expand All @@ -1467,7 +1467,7 @@ public static StringBuilder ScientificAppendTo(UInt64 value, StringBuilder text)
UInt64 coefficient = Unpack(value, out sign, out exponent);

if (coefficient == 0)
return text.Append("0.000000000000000e+000");
return text.Append('0').Append(decimalMark).Append("000000000000000e+000");

exponent -= BaseExponent;

Expand All @@ -1490,7 +1490,7 @@ public static StringBuilder ScientificAppendTo(UInt64 value, StringBuilder text)

bi--;
*bi = *(bi + 1);
*(bi + 1) = '.';
*(bi + 1) = decimalMark;

if (sign)
*--bi = '-';
Expand Down
Loading

0 comments on commit 502cbd7

Please sign in to comment.