Извините, ребята, но оба вопрос и популярный ответ пока неверны: -)
Вопрос неправильный, потому что Тиндалл просит путь к раунду , но показывает пример усечения .
Будет ли ответ Дина неверным, поскольку он также обращается к усечению , а не округлению . (Полагаю, можно утверждать, что ответ правильный на один из двух вопросов, но давайте пока оставим философию в стороне ...)
Вот простая техника для округления :
int precision = 2; // Specify how many digits past the decimal point
TimeSpan t1 = new TimeSpan(19365678); // sample input value
const int TIMESPAN_SIZE = 7; // it always has seven digits
// convert the digitsToShow into a rounding/truncating mask
int factor = (int)Math.Pow(10,(TIMESPAN_SIZE - precision));
Console.WriteLine("Input: " + t1);
TimeSpan truncatedTimeSpan = new TimeSpan(t1.Ticks - (t1.Ticks % factor));
Console.WriteLine("Truncated: " + truncatedTimeSpan);
TimeSpan roundedTimeSpan =
new TimeSpan(((long)Math.Round((1.0*t1.Ticks/factor))*factor));
Console.WriteLine("Rounded: " + roundedTimeSpan);
При вводе значения и количества цифр в примере кода это вывод:
Input: 00:00:01.9365678
Truncated: 00:00:01.9300000
Rounded: 00:00:01.9400000
Измените точность от 2 до 5 цифр и получите вместо этого:
Input: 00:00:01.9365678
Truncated: 00:00:01.9365600
Rounded: 00:00:01.9365700
И даже изменить его на 0, чтобы получить этот результат:
Input: 00:00:01.9365678
Truncated: 00:00:01
Rounded: 00:00:02
Наконец, если вы хотите немного больше контроля над выводом, добавьте немного форматирования. Вот один пример, показывающий, что вы можете отделить точность от количества отображаемых цифр. Точность снова устанавливается равной 2, но отображаются 3 цифры, как указано в последнем аргументе строки управления форматированием:
Console.WriteLine("Rounded/formatted: " +
string.Format("{0:00}:{1:00}:{2:00}.{3:000}",
roundedTimeSpan.Hours, roundedTimeSpan.Minutes,
roundedTimeSpan.Seconds, roundedTimeSpan.Milliseconds));
// Input: 00:00:01.9365678
// Truncated: 00:00:01.9300000
// Rounded: 00:00:01.9400000
// Rounded/formatted: 00:00:01.940
2010.01.06 ОБНОВЛЕНИЕ: готовое решение
Приведенный выше материал полезен, если вы ищете идеи; С тех пор у меня было время реализовать упакованное решение для тех, кто ищет готовый код.
Обратите внимание, что это некомментированный код. Полностью прокомментированная версия с XML-doc-комментариями будет доступна в моей библиотеке с открытым исходным кодом к концу квартала. Несмотря на то, что я не решался опубликовать его в «сыром» виде, я думаю, что он все еще может быть полезным для заинтересованных читателей.
Этот код улучшает мой код выше, который, хотя он и округлен, все же показывает 7 мест, дополненных нулями. Эта законченная версия округляется и обрезается до указанного количества цифр.
Вот пример вызова:
Console.Write(new RoundedTimeSpan(19365678, 2).ToString());
// Result = 00:00:01.94
А вот полный файл RoundedTimeSpan.cs:
using System;
namespace CleanCode.Data
{
public struct RoundedTimeSpan
{
private const int TIMESPAN_SIZE = 7; // it always has seven digits
private TimeSpan roundedTimeSpan;
private int precision;
public RoundedTimeSpan(long ticks, int precision)
{
if (precision < 0) { throw new ArgumentException("precision must be non-negative"); }
this.precision = precision;
int factor = (int)System.Math.Pow(10, (TIMESPAN_SIZE - precision));
// This is only valid for rounding milliseconds-will *not* work on secs/mins/hrs!
roundedTimeSpan = new TimeSpan(((long)System.Math.Round((1.0 * ticks / factor)) * factor));
}
public TimeSpan TimeSpan { get { return roundedTimeSpan; } }
public override string ToString()
{
return ToString(precision);
}
public string ToString(int length)
{ // this method revised 2010.01.31
int digitsToStrip = TIMESPAN_SIZE - length;
string s = roundedTimeSpan.ToString();
if (!s.Contains(".") && length == 0) { return s; }
if (!s.Contains(".")) { s += "." + new string('0', TIMESPAN_SIZE); }
int subLength = s.Length - digitsToStrip;
return subLength < 0 ? "" : subLength > s.Length ? s : s.Substring(0, subLength);
}
}
}
2010.02.01 ОБНОВЛЕНИЕ: теперь доступно пакетное решение
Я только что выпустил новую версию своих библиотек с открытым исходным кодом вчера, раньше, чем ожидалось, включая RoundedTimeSpan, который я описал выше. Код здесь ; для API запустите здесь , затем перейдите к RoundedTimeSpan
в пространстве имен CleanCode.Data
. Библиотека CleanCode.DLL включает в себя код, показанный выше, но предоставляет его в готовом пакете. Обратите внимание, что я немного улучшил метод ToString(int)
, описанный выше, с тех пор, как опубликовал его в 2010.01.06.