Десятичная разница в точности для операций типа (x * = val / b vs x = x * val / b) [duplicate]

Сообщение об ошибке связано с типом «a» в вашем закрытии.

 My_KMV = My_KV.reduce(lambda a, b: a.append([b]))

Пусть pySpark явно оценивает a как список. Например,

My_KMV = My_KV.reduceByKey(lambda a,b:[a].extend([b]))

Во многих случаях reduceByKey будет предпочтительнее groupByKey, обратитесь к: http://databricks.gitbooks.io/databricks-spark-knowledge-base/content/ best_practices / prefer_reducebykey_over_groupbykey.html

61
задан Amy B 15 July 2009 в 18:24
поделиться

7 ответов

Сохранение конечных нулей, подобных этому, было введено в .NET 1.1 для более строгого соответствия спецификации ECI CLI.

В MSDN имеется некоторая информация об этом. здесь .

Вы можете отрегулировать точность следующим образом:

  • Math.Round (или потолок, пол и т. д.) для уменьшения точности (b от c)
  • Умножьте на 1.000 ... (с количеством десятичных знаков, которые вы хотите), чтобы повысить точность - например умножьте на 1.0M, чтобы получить b из.
47
ответ дан Joe 26 August 2018 в 23:20
поделиться
  • 1
    Также разделите на 1.000..., чтобы уменьшить точность. – Jeppe Stig Nielsen 26 August 2013 в 14:41

Я обнаружил, что могу «подделать» шкалу умножением или делением на фантазию 1.

decimal a = 2m;
decimal c = 2.00000000m;
decimal PreciseOne = 1.000000000000000000000000000000m;
  //add maximum trailing zeros to a
decimal x = a * PreciseOne;
  //remove all trailing zeros from c
decimal y = c / PreciseOne;

Я могу изготовить достаточно точный 1 для изменения масштабных коэффициентов по известным размерам.

decimal scaleFactorBase = 1.0m;
decimal scaleFactor = 1m;
int scaleFactorSize = 3;

for (int i = 0; i < scaleFactorSize; i++)
{
  scaleFactor *= scaleFactorBase;
}

decimal z = a * scaleFactor;
5
ответ дан Amy B 26 August 2018 в 23:20
поделиться
  • 1
    Интересно, но в то же время загадочно. В чем разница между 2.0m и 2.00000000m? В не-вычислительной среде я бы сказал, что это последнее число гарантировалось этой точностью, тогда как первая была гарантирована только первой десятичной точкой. Однако умножение должно означать, что результат может быть точным только с одним десятичным знаком. – sgmoore 15 July 2009 в 21:42

Заманчиво путать decimal в SQL Server с decimal в .NET; они совершенно разные.

SQL Server decimal - это номер фиксированной точки, точность и масштаб которого фиксированы при определении столбца или переменной.

A .NET decimal - это число с плавающей запятой, например float и double (разница в том, что decimal точно сохраняет десятичные цифры, тогда как float и double точно сохраняют двоичные цифры). Попытка контролировать точность .NET decimal бессмысленна, поскольку все вычисления дают одинаковые результаты независимо от наличия или отсутствия нулей заполнения.

5
ответ дан Christian Hayter 26 August 2018 в 23:20
поделиться
  • 1
    интересно, что установка граней в десятичной дроби в EF создает правильный SQL decimal, который быстро терпит неудачу, когда ему передается c# decimal ... в моем случае я использовал Precision: 2, Scale: (none), и я не могу назначить 800 к нему из-за того, что значение вне диапазона – ekkis 27 September 2011 в 01:00

Вы просто видите разные представления одних и тех же данных.

Из System.Decimal :

Точность decimal будет масштабироваться так, чтобы она была (по причине)

Десятичное число - это значение с плавающей запятой, которое состоит из знака, числового значения, где каждая цифра в значении находится в диапазоне от 0 до 9, и коэффициент масштабирования, который указывает положение плавающей десятичной точки, которая разделяет интегральную и дробную части числового значения.

Двоичное представление десятичного значения состоит из 1-битового знака, 96-битного целочисленного числа и коэффициента масштабирования, используемого для разделите 96-битное целое число и укажите, какая часть его является десятичной дробью. Коэффициент масштабирования неявно равен числу 10, поднятому до экспоненты в диапазоне от 0 до 28. Следовательно, двоичное представление десятичного значения имеет вид ((от -296 до 296) / 10 (от 0 до 28)), где -296-1 равно MinValue, а 296-1 равно MaxValue.

Масштабный коэффициент также сохраняет любые конечные нули в десятичном числе. Конечные нули не влияют на значение десятичного числа в арифметических или сравнительных операциях. Однако конечные нули могут быть обнаружены методом ToString, если применяется соответствующая строка формата.

18
ответ дан Roman Starkov 26 August 2018 в 23:20
поделиться
  • 1
    Хорошая информация о масштабирующем коэффициенте ... теперь, как я могу его настроить? – Amy B 15 July 2009 в 18:33
  • 2
    Масштабный коэффициент не контролируется напрямую, поскольку он настраивается в зависимости от размера экспоненты. В основном это работает с плавающей точкой (и откуда берется термин «плавающий»). Поскольку число бит в значении является постоянным, размер числа определяет масштаб значимых бит. – codekaizen 15 July 2009 в 18:57
  • 3
    Он автоматически настраивается для соответствия потребностям содержащихся в нем данных. Есть ли конкретная причина, по которой вам нужно масштабировать ее вручную? – Andrew Hare 15 July 2009 в 18:58
  • 4
    Есть причина - однако я чувствую, что причина не добавляет ясности к этому вопросу. Я, вероятно, задаю отдельный вопрос о причине. – Amy B 15 July 2009 в 19:42
  • 5
    @David - звучит хорошо. – Andrew Hare 15 July 2009 в 19:43

Вопрос в том, действительно ли вам нужна точность, хранящаяся в десятичной системе, а не просто отображение десятичной точки в требуемую точность. Большинство приложений знают внутренне, насколько точны они хотят быть и демонстрировать этот уровень точности. Например, даже если пользователь вводит счет-фактуру за 100 в пакете учетных записей, он все равно печатает как 100.00, используя что-то вроде val.ToString («n2»).

Как я могу создать b из? Как я могу создать b из c?

c в b.

Console.WriteLine(Math.Round(2.00000000m, 1)) 

производит 2.0

a to b является сложным, поскольку концепция введения точности немного чуждо математике.

Я предполагаю, что ужасный взлом может быть в оба конца.

decimal b = Decimal.Parse(a.ToString("#.0"));
Console.WriteLine(b);

производит 2.0

1
ответ дан sgmoore 26 August 2018 в 23:20
поделиться

Это приведет к удалению всех конечных нулей из десятичной дроби, а затем вы можете просто использовать ToString().

public static class DecimalExtensions
{
    public static Decimal Normalize(this Decimal value)
    {
        return value / 1.000000000000000000000000000000000m;
    }
}

Или, если вы хотите, чтобы точное количество завершающих нулей, скажем, 5, сначала Normalize (), а затем умножьте на 1.00000 м.

0
ответ дан shamp00 26 August 2018 в 23:20
поделиться

Что относительно Math.Round (десятичный d, int decimals) ?

6
ответ дан Tadas Šukys 26 August 2018 в 23:20
поделиться
  • 1
    Для значений .00 вам нужно будет умножить на 1.00m сначала: decimal.Round (значение * 1.00m, 2) – user1073075 3 November 2016 в 11:38
Другие вопросы по тегам:

Похожие вопросы: