I'm trying to format a number in a very specific way when displaying it, I've tried messing around with String.Format but couldn't find a way to make this work exactly as I needed.
For example, let's way that I have a variable of type Double with the value "123459.7889" and that I want to format it as "459.788" (000.000) but only during Console.WriteLine() and without rounding or changing the internal value of the number. The full value of the number would not show up and it should technically "overflow" the string because it should only print the first 3 numbers to the left of the decimal point.
Here are some example inputs and example outputs:
12345.678 formatted to "000.000" would become 345.678
1000000.678 formatted to "000.000" would become 000.678
1.777888 formatted to "000.000" would become 001.777
99999.9 formatted to "000.000" would become 999.900
Basically, no matter the internal size of the number, the formatted output should always be the 3 numbers to the left of the decimal point and the 3 numbers to the right of the decimal point with zeros to replace the missing spaces if there's any.
I've tried looking at the examples on the C# documentation and found this:
double value = 123459.7889;
string result = String.Format("{0,8:00000000} {0,8:00000000.000}", value);
Console.WriteLine(result);
But it doesn't work exactly like I needed it to. When running it the numbers are rounded so it becomes 00123459.789 instead of 00123459.788 for example and if the number grows it no longer stays at that fixed size.
CodePudding user response:
try this:
double value = 123459.7889;
Console.WriteLine((Math.Truncate(Math.Abs(value) % 1000) double.Parse((Math.Round(Math.Abs(value), 3, MidpointRounding.ToZero) -
Math.Truncate(Math.Abs(value))).ToString(".000"))).ToString("000.000"));
value= 123459.7889; result=345.678
value= 1000000.678; result=000.678
value= 1.777888; result=001.777
value= 99999.9; result=999.900
value= 152; result=152 .000
value= -100.02; result=100.020
value= 10.0005; result=010.000
CodePudding user response:
You shouldn't need to convert to string, nor should you rely on splitting on a character that may or may not be the decimal character in the language you are running. You can do all the calculations on the numbers and then format the output without allocating any strings except for the result.
public static string FormatNumber(double number)
{
int first = ((int)number)00;
int second = (int)Math.Truncate((number-(int)number)*1000)00;
return $"{first:000}.{second:000}";
}
CodePudding user response:
We can use PadLeft
and PadRight
to fill up zeros when value characters are not enough.
Implementation:
static void Main(string[] args)
{
double value = 1.12;
string valueStr = value.ToString().Replace("-", ""); // convert to string
// check if value does not contain decimal and add
if (!valueStr.ToString().Contains("."))
valueStr = valueStr ".0"; // add decimal part
var arr = valueStr.ToString().Split(".");
string intValue = arr[0]; //1
intValue = intValue.PadLeft(3,'0'); //001
intValue = intValue.Substring(intValue.Length - 3, 3); //001
string decimalValue = arr[1]; //12
decimalValue = decimalValue.PadRight(3,'0'); //120
decimalValue = decimalValue.Substring(0, 3); //120
string result = $"{intValue}.{decimalValue}";
Console.WriteLine(result);
}
Result:
12345.678 > 345.678
1000000.678 > 000.678
1.777888 > 001.777
99999.9 > 999.900
152 > 152.000
-100.02 > 100.020
-10.0005 > 010.000
CodePudding user response:
static string Format(double number)
{
return string.Format("{0:N3}", number % 1000).PadLeft(7,'0');
}
How it works:
- Remove the upper digits using modulus (
%
) - Format to three decimal places using a format string
- Pad left using
PadLeft()
Full example:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var tests = new Dictionary<double,string>
{
{ 12345.678D, "345.678" },
{ 1000000.678, "000.678" },
{ 1.777888, "001.778" },
{ 99999.9, "999.900"}
};
foreach (var pair in tests)
{
Console.WriteLine("Expected: {0} Actual: {1}", pair.Value, Format(pair.Key));
}
}
static string Format(double number)
{
return string.Format("{0:N3}", number % 1000).PadLeft(7,'0');
}
}
Output:
Expected: 345.678 Actual: 345.678
Expected: 000.678 Actual: 000.678
Expected: 001.778 Actual: 001.778
Expected: 999.900 Actual: 999.900
CodePudding user response:
try this
int i = value.ToString().IndexOf(".");
string result = string.Concat(value.ToString().Substring(i - 3, 3),".", value.ToString().Substring(i 1, 3));
Console.WriteLine(result);