2,50 - это всего 2,5. Я полагаю, вы говорите о струнах.
Тим Шмелтер
3
Вы всегда возвращаете первые две цифры после запятой? Является ли ввести decimal, float, string, ...?
Грег
3
Пример использования имеет большое значение для получения качественных ответов в следующий раз.
tmesser
да, только две цифры, ввод десятичный
user1095549
4
Команда разработчиков C # должна быть смущена (и должна принять меры) из-за того, что эта очень распространенная операция не имеет единственной функции Math., такой как Math.DecimalPart (двойной x) или что-то в этом роде. Слишком много слов «вы пробовали это, вы думали об этом» для того, что многим из нас нужно делать часто.
philologon
Ответы:
-21
Обновленный ответ
Здесь я даю 3 подхода к одному и тому же.
[1] Математическое решение с использованием Math.Truncate
var float_number = 12.345;
var result = float_number - Math.Truncate(float_number);
// ввод: 1.05
// вывод: "0.050000000000000044"
// ввод: 10.2
// вывод: 0.19999999999999929
Если это не тот результат, которого вы ожидаете, вам необходимо изменить результат на желаемую форму (но вы можете снова выполнить некоторые манипуляции со строками).
[2] с использованием множителя [который равен 10 в степени N (например, 10² или 10³), где N - количество десятичных знаков]
// multiplier is " 10 to the power of 'N'" where 'N' is the number // of decimal placesint multiplier = 1000;
double double_value = 12.345;
int double_result = (int)((double_value - (int)double_value) * multiplier);
// вывод 345
Если количество десятичных знаков не фиксировано, такой подход может создать проблемы.
[3] с использованием «Регулярных выражений (REGEX)»
мы должны быть очень осторожны при написании решений со строкой. Это было бы нежелательно, за исключением некоторых случаев.
Если вы собираетесь выполнять строковые операции с десятичными знаками, это будет предпочтительнее
string input_decimal_number = "1.50";
var regex = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+");
if (regex.IsMatch(input_decimal_number))
{
string decimal_places = regex.Match(input_decimal_number).Value;
}
Будьте осторожны с ToString (), поскольку он не будет возвращать десятичных частей для целых чисел, то есть, если MyValue равно 3, MyValue.ToString () вернет «3», поэтому Split ('.') [1] выдаст. Подумайте о том, чтобы явно указать формат необходимого количества десятичных знаков: MyValue.ToString ("F2"). Split ('.') [1]
Alex Beynenson
7
Это решение примерно на два порядка медленнее, чем любое другое решение на этой странице, и на четыре порядка медленнее, чем мой собственный ответ.
tmesser
1
Это решение зависит от культуры. Например, для русского и английского-американского языков используются разные десятичные разделители (запятая и точка соответственно). Таким образом, этот код не будет работать при настройке других культур.
Юрий Щкатула
2
Это решение разбивается на .десятичный разделитель, который не всегда является десятичным разделителем (например, в Европе используется десятичный разделитель ,). Вы должны добавить, CultureInfo.Invariantчтобы сделать его международным. Хотя проще использовать x - Math.Truncate(x)и творить чудеса с этим результатом.
Это должен быть принятый ответ, математическое решение математического вопроса, без всей этой утомительной возни с манипуляциями со строками
johnc 01
20
Думаю, у этого решения есть «проблема». Если floatNumber был «10,2», переменная x будет иметь вид «0,19999999999999929». Даже если это сработает, как ожидалось, результат будет «0,2», а не «2».
Dherik
4
Значения @Dherik Float и Double всегда имеют небольшие ошибки при вычитании в последних нескольких десятичных разрядах. Вы не должны считать их значительными. Если вам действительно нужна такая точность, вы должны использовать тип Decimal. Если вы не можете переключиться на Decimal (или просто не хотите), вам следует как-то отслеживать ожидаемую точность и учитывать это в операциях сравнения. Обычно я использую 4 знака после запятой, но из этого могут быть исключения.
philologon
Из msdn.microsoft.com/en-us/library/… : «Поскольку некоторые числа не могут быть представлены точно как дробные двоичные значения, числа с плавающей запятой могут быть только приближенными к действительным числам»
philologon
1
Заключительный комментарий: использование Math.Truncate было намерением автора библиотеки Math для такого рода ситуаций. Ответ @Matterai должен быть принятым.
philologon
81
var decPlaces = (int)(((decimal)number % 1) * 100);
Это предполагает, что ваш номер имеет только два десятичных знака.
(318.40d % 1) * 100выходов 39.9999999999977, вы можете использовать приведение, чтобы обойти ошибку округления:var decPlaces = (int)(((decimal)number % 1) * 100);
orad
@orad Хороший прием - числа с плавающей запятой всегда имеют эти небольшие неточности, поэтому приведение их к типу довольно благоразумно, чтобы обеспечить согласованное поведение. Я обновлю свой ответ, хотя Маттераи все еще более технически правильный.
tmesser
27
Существует более чистое и более быстрое решение, чем подход Math.Truncate:
примечание: для отрицательных значений это отрицательное значение : -12.34% 1 => -0.33999999999999986
Alex
16
Решение без проблемы округления:
double number = 10.20;
var first2DecimalPlaces = (int)(((decimal)number % 1) * 100);
Console.Write("{0:00}", first2DecimalPlaces);
Выходы:20
Обратите внимание, если бы мы не преобразовали в десятичный формат, он бы выводил 19.
Также:
для 318.40выходов: 40(вместо39)
для 47.612345выходов: 61(вместо612345)
для 3.01выходов: 01(вместо 1)
Если вы работаете с финансовыми числами, например, если в этом случае вы пытаетесь получить центовую часть суммы транзакции, всегда используйте этот decimalтип данных.
Обновить:
Следующее также будет работать, если обработать его как строку (на основе ответа @ SearchForKnowledge).
Вопрос в том, чтобы получить первые 2 десятичные цифры. Для числа 318.401567dваше решение выводит 0.401567где 40ожидается.
orad
0
publicstaticstringFractionPart(thisdouble instance)
{
var result = string.Empty;
var ic = CultureInfo.InvariantCulture;
var splits = instance.ToString(ic).Split(new[] { ic.NumberFormat.NumberDecimalSeparator }, StringSplitOptions.RemoveEmptyEntries);
if (splits.Count() > 1)
{
result = splits[1];
}
return result;
}
Вот метод расширения, который я написал для аналогичной ситуации. Мое приложение получало числа в формате 2.3 или 3.11, где целочисленный компонент числа представлял годы, а дробный компонент - месяцы.
// Sample Usageint years, months;
double test1 = 2.11;
test1.Split(out years, out months);
// years = 2 and months = 11publicstaticclassDoubleExtensions
{
publicstaticvoidSplit(thisdouble number, outint years, outint months)
{
years = Convert.ToInt32(Math.Truncate(number));
double tempMonths = Math.Round(number - years, 2);
while ((tempMonths - Math.Floor(tempMonths)) > 0 && tempMonths != 0) tempMonths *= 10;
months = Convert.ToInt32(tempMonths);
}
}
Было бы здорово, если бы вы могли добавить описание того, как регулярное выражение помогает в решении проблемы
Клептус
-1
Вы можете удалить точку .с двойного числа, которое вы пытаетесь получить десятичные дроби, используяRemove() функции после преобразования двойного в строку, чтобы вы могли выполнять необходимые операции с ним.
Рассмотрите возможность использования двойного _Doubleзначения 0.66781, следующий код будет показывать только числа после точки, .которые66781
double _Double = 0.66781; //Declare a new double with a value of 0.66781string _Decimals = _Double.ToString().Remove(0, _Double.ToString().IndexOf(".") + 1); //Remove everything starting with index 0 and ending at the index of ([the dot .] + 1)
Другое решение
Вы также можете использовать класс, Pathкоторый выполняет операции с экземплярами строк кроссплатформенным способом.
double _Double = 0.66781; //Declare a new double with a value of 0.66781string Output = Path.GetExtension(D.ToString()).Replace(".",""); //Get (the dot and the content after the last dot available and replace the dot with nothing) as a new string object Output//Do something
Не очень популярен, Regex.Matchно я получил следующую ошибку при попытке получить значение десятичной дробиArgumentException was unhandled: parsing "\.(?\d+)" - Unrecognized grouping construct.
Picrofo Software
-2
Это очень просто
float moveWater = Mathf.PingPong(theTime * speed, 100) * .015f;
int m = (int)(moveWater);
float decimalPart= moveWater -m ;
Debug.Log(decimalPart);
decimal
,float
,string
, ...?Ответы:
Обновленный ответ
Здесь я даю 3 подхода к одному и тому же.
[1] Математическое решение с использованием Math.Truncate
var float_number = 12.345; var result = float_number - Math.Truncate(float_number);
// ввод: 1.05
// вывод: "0.050000000000000044"
// ввод: 10.2
// вывод: 0.19999999999999929
Если это не тот результат, которого вы ожидаете, вам необходимо изменить результат на желаемую форму (но вы можете снова выполнить некоторые манипуляции со строками).
[2] с использованием множителя [который равен 10 в степени N (например, 10² или 10³), где N - количество десятичных знаков]
// multiplier is " 10 to the power of 'N'" where 'N' is the number // of decimal places int multiplier = 1000; double double_value = 12.345; int double_result = (int)((double_value - (int)double_value) * multiplier);
// вывод 345
Если количество десятичных знаков не фиксировано, такой подход может создать проблемы.
[3] с использованием «Регулярных выражений (REGEX)»
мы должны быть очень осторожны при написании решений со строкой. Это было бы нежелательно, за исключением некоторых случаев.
Если вы собираетесь выполнять строковые операции с десятичными знаками, это будет предпочтительнее
string input_decimal_number = "1.50"; var regex = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+"); if (regex.IsMatch(input_decimal_number)) { string decimal_places = regex.Match(input_decimal_number).Value; }
// ввод: «1.05»
// вывод: «05»
// ввод: "2.50"
// вывод: "50"
// ввод: «0,0550»
// вывод: «0550»
вы можете найти больше о Regex на http://www.regexr.com/
источник
.
десятичный разделитель, который не всегда является десятичным разделителем (например, в Европе используется десятичный разделитель,
). Вы должны добавить,CultureInfo.Invariant
чтобы сделать его международным. Хотя проще использоватьx - Math.Truncate(x)
и творить чудеса с этим результатом.лучший из лучших способов:
var floatNumber = 12.5523; var x = floatNumber - Math.Truncate(floatNumber);
результат вы можете конвертировать, как хотите
источник
var decPlaces = (int)(((decimal)number % 1) * 100);
Это предполагает, что ваш номер имеет только два десятичных знака.
источник
(318.40d % 1) * 100
выходов39.9999999999977
, вы можете использовать приведение, чтобы обойти ошибку округления:var decPlaces = (int)(((decimal)number % 1) * 100);
Существует более чистое и более быстрое решение, чем подход Math.Truncate:
double frac = value % 1;
источник
Решение без проблемы округления:
double number = 10.20; var first2DecimalPlaces = (int)(((decimal)number % 1) * 100); Console.Write("{0:00}", first2DecimalPlaces);
Выходы:
20
Также:
318.40
выходов:40
(вместо39
)47.612345
выходов:61
(вместо612345
)3.01
выходов:01
(вместо1
)Обновить:
Следующее также будет работать, если обработать его как строку (на основе ответа @ SearchForKnowledge).
10.2d.ToString("0.00", CultureInfo.InvariantCulture).Split('.')[1]
Затем вы можете использовать его
Int32.Parse
для преобразования в int.источник
Лучший способ -
double value = 10.567; int result = (int)((value - (int)value) * 100); Console.WriteLine(result);
Вывод -
56
источник
10.20
он будет выводить19
. Смотрите мой ответ.Самый простой вариант, возможно, с Math.truncate ()
double value = 1.761 double decPart = value - Math.truncate(value)
источник
Думаю, эта ветка устаревает, но я не могу поверить, что никто не упомянул Math.Floor
//will always be .02 cents (10.02m - System.Math.Floor(10.02m))
источник
double fract(double x) { return x - System.Math.Floor(x); }
var result = number.ToString().Split(System.Globalization.NumberDecimalSeparator)[2]
Возвращает его как строку (но вы всегда можете преобразовать ее обратно в int) и предполагает, что число имеет "." где-то.
источник
int last2digits = num - (int) ((double) (num / 100) * 100);
источник
318.401567d
ваше решение выводит0.401567
где40
ожидается.public static string FractionPart(this double instance) { var result = string.Empty; var ic = CultureInfo.InvariantCulture; var splits = instance.ToString(ic).Split(new[] { ic.NumberFormat.NumberDecimalSeparator }, StringSplitOptions.RemoveEmptyEntries); if (splits.Count() > 1) { result = splits[1]; } return result; }
источник
Вот метод расширения, который я написал для аналогичной ситуации. Мое приложение получало числа в формате 2.3 или 3.11, где целочисленный компонент числа представлял годы, а дробный компонент - месяцы.
// Sample Usage int years, months; double test1 = 2.11; test1.Split(out years, out months); // years = 2 and months = 11 public static class DoubleExtensions { public static void Split(this double number, out int years, out int months) { years = Convert.ToInt32(Math.Truncate(number)); double tempMonths = Math.Round(number - years, 2); while ((tempMonths - Math.Floor(tempMonths)) > 0 && tempMonths != 0) tempMonths *= 10; months = Convert.ToInt32(tempMonths); } }
источник
Это может быть накладными расходами, но должно работать.
double yourDouble = 1.05; string stringForm = yourDouble.ToString(); int dotPosition = stringForm.IndexOf("."); decimal decimalPart = Decimal.Parse("0" + stringForm.Substring(dotPosition)); Console.WriteLine(decimalPart); // 0.05
источник
string input = "0.55"; var regex1 = new System.Text.RegularExpressions.Regex("(?<=[\\.])[0-9]+"); if (regex1.IsMatch(input)) { string dp= regex1.Match(input ).Value; }
источник
Вы можете удалить точку
.
с двойного числа, которое вы пытаетесь получить десятичные дроби, используяRemove()
функции после преобразования двойного в строку, чтобы вы могли выполнять необходимые операции с ним.Рассмотрите возможность использования двойного
_Double
значения0.66781
, следующий код будет показывать только числа после точки,.
которые66781
double _Double = 0.66781; //Declare a new double with a value of 0.66781 string _Decimals = _Double.ToString().Remove(0, _Double.ToString().IndexOf(".") + 1); //Remove everything starting with index 0 and ending at the index of ([the dot .] + 1)
Другое решение
Вы также можете использовать класс,
Path
который выполняет операции с экземплярами строк кроссплатформенным способом.double _Double = 0.66781; //Declare a new double with a value of 0.66781 string Output = Path.GetExtension(D.ToString()).Replace(".",""); //Get (the dot and the content after the last dot available and replace the dot with nothing) as a new string object Output //Do something
источник
Используйте регулярное выражение:
Regex.Match("\.(?\d+)")
кто-нибудь поправит меня, если я ошибаюсьисточник
Regex.Match
но я получил следующую ошибку при попытке получить значение десятичной дробиArgumentException was unhandled: parsing "\.(?\d+)" - Unrecognized grouping construct.
Это очень просто
float moveWater = Mathf.PingPong(theTime * speed, 100) * .015f; int m = (int)(moveWater); float decimalPart= moveWater -m ; Debug.Log(decimalPart);
источник
Почему бы не использовать
int y = value.Split('.')[1];
?Split()
Функция разбивает значение в отдельный контент и1
выводит 2 - ое значение после.
источник
Int32.Parse((12.05123d.ToString("0.00").Split('.')[1]))