Added overloads for the StringBuilderHelper.Append() method to limit the number of decimal places being displayed; wrote unit tests for the new functionality
git-svn-id: file:///srv/devel/repo-conversion/nusu@190 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
03eb31403d
commit
35a4da16fc
|
@ -166,6 +166,26 @@ namespace Nuclex.Support {
|
|||
Assert.AreEqual("1000000000.0", builder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Tests whether the number of decimal places can be restricted</summary>
|
||||
[Test]
|
||||
public void TestAppendFloatLimitDecimalPlaces() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilderHelper.Append(builder, 0.00390625f, 3);
|
||||
|
||||
Assert.AreEqual("0.003", builder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a float with no decimal places is correctly appended
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAppendFloatWithoutDecimalPlaces() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilderHelper.Append(builder, 0.00390625f, 0);
|
||||
|
||||
Assert.AreEqual("0", builder.ToString()); // Note: no rounding!
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the behavior of the helper with unsupported floating point values
|
||||
/// </summary>
|
||||
|
@ -226,6 +246,26 @@ namespace Nuclex.Support {
|
|||
Assert.AreEqual("1000000000000000000.0", builder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>Tests whether the number of decimal places can be restricted</summary>
|
||||
[Test]
|
||||
public void TestAppendDoubleLimitDecimalPlaces() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilderHelper.Append(builder, 0.00390625, 3);
|
||||
|
||||
Assert.AreEqual("0.003", builder.ToString()); // Note: no rounding!
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that a double with no decimal places is correctly appended
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAppendDoubleWithoutDecimalPlaces() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilderHelper.Append(builder, 0.00390625, 0);
|
||||
|
||||
Assert.AreEqual("0", builder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the behavior of the helper with unsupported double precision
|
||||
/// floating point values
|
||||
|
|
|
@ -103,6 +103,22 @@ namespace Nuclex.Support {
|
|||
/// is returned and the traditional double.ToString() method can be used.
|
||||
/// </remarks>
|
||||
public static bool Append(StringBuilder builder, float value) {
|
||||
return Append(builder, value, int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a floating point value to a string builder without generating garbage
|
||||
/// </summary>
|
||||
/// <param name="builder">String builder the value will be appended to</param>
|
||||
/// <param name="value">Value that will be appended to the string builder</param>
|
||||
/// <param name="decimalPlaces">Maximum number of decimal places to display</param>
|
||||
/// <returns>Whether the value was inside the algorithm's supported range</returns>
|
||||
/// <remarks>
|
||||
/// Uses an algorithm that covers the sane range of possible values but will
|
||||
/// fail to render extreme values, NaNs and infinity. In these cases, false
|
||||
/// is returned and the traditional double.ToString() method can be used.
|
||||
/// </remarks>
|
||||
public static bool Append(StringBuilder builder, float value, int decimalPlaces) {
|
||||
const int ExponentBits = 0xFF; // Bit mask for the exponent bits
|
||||
const int FractionalBitCount = 23; // Number of bits for fractional part
|
||||
const int ExponentBias = 127; // Bias subtraced from exponent
|
||||
|
@ -148,17 +164,24 @@ namespace Nuclex.Support {
|
|||
recursiveAppend(builder, integral);
|
||||
}
|
||||
|
||||
builder.Append('.');
|
||||
if(decimalPlaces > 0) {
|
||||
builder.Append('.');
|
||||
|
||||
// Build the fractional part
|
||||
if(fractional == 0) {
|
||||
builder.Append('0');
|
||||
} else {
|
||||
while(fractional != 0) {
|
||||
fractional *= 10;
|
||||
int digit = (fractional >> FractionalBitCountPlusOne);
|
||||
builder.Append(numbers[digit]);
|
||||
fractional &= FractionalBits;
|
||||
// Build the fractional part
|
||||
if(fractional == 0) {
|
||||
builder.Append('0');
|
||||
} else {
|
||||
while(fractional != 0) {
|
||||
fractional *= 10;
|
||||
int digit = (fractional >> FractionalBitCountPlusOne);
|
||||
builder.Append(numbers[digit]);
|
||||
fractional &= FractionalBits;
|
||||
|
||||
--decimalPlaces;
|
||||
if(decimalPlaces == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +201,23 @@ namespace Nuclex.Support {
|
|||
/// is returned and the traditional double.ToString() method can be used.
|
||||
/// </remarks>
|
||||
public static bool Append(StringBuilder builder, double value) {
|
||||
return Append(builder, value, int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a double precision floating point value to a string builder
|
||||
/// without generating garbage
|
||||
/// </summary>
|
||||
/// <param name="builder">String builder the value will be appended to</param>
|
||||
/// <param name="value">Value that will be appended to the string builder</param>
|
||||
/// <param name="decimalPlaces">Maximum number of decimal places to display</param>
|
||||
/// <returns>Whether the value was inside the algorithm's supported range</returns>
|
||||
/// <remarks>
|
||||
/// Uses an algorithm that covers the sane range of possible values but will
|
||||
/// fail to render extreme values, NaNs and infinity. In these cases, false
|
||||
/// is returned and the traditional double.ToString() method can be used.
|
||||
/// </remarks>
|
||||
public static bool Append(StringBuilder builder, double value, int decimalPlaces) {
|
||||
const long ExponentBits = 0x7FF; // Bit mask for the exponent bits
|
||||
const int FractionalBitCount = 52; // Number of bits for fractional part
|
||||
const int ExponentBias = 1023; // Bias subtraced from exponent
|
||||
|
@ -223,17 +263,24 @@ namespace Nuclex.Support {
|
|||
recursiveAppend(builder, integral);
|
||||
}
|
||||
|
||||
builder.Append('.');
|
||||
if(decimalPlaces > 0) {
|
||||
builder.Append('.');
|
||||
|
||||
// Build the fractional part
|
||||
if(fractional == 0) {
|
||||
builder.Append('0');
|
||||
} else {
|
||||
while(fractional != 0) {
|
||||
fractional *= 10;
|
||||
long digit = (fractional >> FractionalBitCountPlusOne);
|
||||
builder.Append(numbers[digit]);
|
||||
fractional &= FractionalBits;
|
||||
// Build the fractional part
|
||||
if(fractional == 0) {
|
||||
builder.Append('0');
|
||||
} else {
|
||||
while(fractional != 0) {
|
||||
fractional *= 10;
|
||||
long digit = (fractional >> FractionalBitCountPlusOne);
|
||||
builder.Append(numbers[digit]);
|
||||
fractional &= FractionalBits;
|
||||
|
||||
--decimalPlaces;
|
||||
if(decimalPlaces == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user