diff --git a/Source/StringBuilderHelper.Test.cs b/Source/StringBuilderHelper.Test.cs
index 3f63c91..f43766e 100644
--- a/Source/StringBuilderHelper.Test.cs
+++ b/Source/StringBuilderHelper.Test.cs
@@ -166,6 +166,26 @@ namespace Nuclex.Support {
Assert.AreEqual("1000000000.0", builder.ToString());
}
+ /// Tests whether the number of decimal places can be restricted
+ [Test]
+ public void TestAppendFloatLimitDecimalPlaces() {
+ StringBuilder builder = new StringBuilder();
+ StringBuilderHelper.Append(builder, 0.00390625f, 3);
+
+ Assert.AreEqual("0.003", builder.ToString());
+ }
+
+ ///
+ /// Verifies that a float with no decimal places is correctly appended
+ ///
+ [Test]
+ public void TestAppendFloatWithoutDecimalPlaces() {
+ StringBuilder builder = new StringBuilder();
+ StringBuilderHelper.Append(builder, 0.00390625f, 0);
+
+ Assert.AreEqual("0", builder.ToString()); // Note: no rounding!
+ }
+
///
/// Verifies the behavior of the helper with unsupported floating point values
///
@@ -226,6 +246,26 @@ namespace Nuclex.Support {
Assert.AreEqual("1000000000000000000.0", builder.ToString());
}
+ /// Tests whether the number of decimal places can be restricted
+ [Test]
+ public void TestAppendDoubleLimitDecimalPlaces() {
+ StringBuilder builder = new StringBuilder();
+ StringBuilderHelper.Append(builder, 0.00390625, 3);
+
+ Assert.AreEqual("0.003", builder.ToString()); // Note: no rounding!
+ }
+
+ ///
+ /// Verifies that a double with no decimal places is correctly appended
+ ///
+ [Test]
+ public void TestAppendDoubleWithoutDecimalPlaces() {
+ StringBuilder builder = new StringBuilder();
+ StringBuilderHelper.Append(builder, 0.00390625, 0);
+
+ Assert.AreEqual("0", builder.ToString());
+ }
+
///
/// Verifies the behavior of the helper with unsupported double precision
/// floating point values
diff --git a/Source/StringBuilderHelper.cs b/Source/StringBuilderHelper.cs
index 590e483..e3242d7 100644
--- a/Source/StringBuilderHelper.cs
+++ b/Source/StringBuilderHelper.cs
@@ -103,6 +103,22 @@ namespace Nuclex.Support {
/// is returned and the traditional double.ToString() method can be used.
///
public static bool Append(StringBuilder builder, float value) {
+ return Append(builder, value, int.MaxValue);
+ }
+
+ ///
+ /// Appends a floating point value to a string builder without generating garbage
+ ///
+ /// String builder the value will be appended to
+ /// Value that will be appended to the string builder
+ /// Maximum number of decimal places to display
+ /// Whether the value was inside the algorithm's supported range
+ ///
+ /// 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.
+ ///
+ 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.
///
public static bool Append(StringBuilder builder, double value) {
+ return Append(builder, value, int.MaxValue);
+ }
+
+ ///
+ /// Appends a double precision floating point value to a string builder
+ /// without generating garbage
+ ///
+ /// String builder the value will be appended to
+ /// Value that will be appended to the string builder
+ /// Maximum number of decimal places to display
+ /// Whether the value was inside the algorithm's supported range
+ ///
+ /// 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.
+ ///
+ 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;
+ }
+ }
}
}