Сбой в калькуляторе Google, может всплывать по сравнению сэто может быть возможной причиной?

StackOverflow https://stackoverflow.com/questions/27095

  •  09-06-2019
  •  | 
  •  

Вопрос

Я сделал это просто так (так что, это не совсем вопрос, я вижу, что понижение моды уже происходит), но вместо новообретенного Google неспособность делать математика правильно (проверьте это!согласно Google 500,000,000,000,002 - 500,000,000,000,001 = 0), я решил попробовать следующее на C, чтобы немного развить теорию.

int main()
{
   char* a = "399999999999999";
   char* b = "399999999999998";

   float da = atof(a);
   float db = atof(b);

   printf("%s - %s = %f\n", a, b, da-db);

   a = "500000000000002";
   b = "500000000000001";
   da = atof(a);
   db = atof(b);
   printf("%s - %s = %f\n", a, b, da-db);
}

Когда вы запускаете эту программу, вы получаете следующее

   399999999999999 - 399999999999998 = 0.000000
   500000000000002 - 500000000000001 = 0.000000

Казалось бы, Google использует простую 32-битную точность с плавающей запятой (ошибка здесь), если вы переключите float на double в приведенном выше коде, вы устраните проблему!Может ли это быть оно?

/мп

Это было полезно?

Решение

в C # попробуйте (double.maxvalue == (double.maxvalue - 100)), вы получите true ...

но так оно и должно быть:

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

думая об этом, у вас есть 64 бита, представляющие число, большее 2 ^ 64 (double.maxvalue), поэтому ожидается неточность.

Другие советы

Подробнее о подобных глупостях читайте в этой замечательной статье, относящейся к калькулятору Windows.

Когда вы меняете внутренности, никто этого не замечает

Внутренности Calc - арифметический движок - были полностью выброшены и переписаны с нуля. Стандартная библиотека IEEE с плавающей запятой была заменена на библиотеку арифметики произвольной точности .Это было сделано после того, как люди продолжали писать ха-ха статьи о том, что Calc не может выполнять десятичную арифметику правильно, что, например, вычисления 10.21 - 10.2 привели к 0.0100000000000016.

Казалось бы, Google использует простую 32-битную точность с плавающей запятой (ошибка здесь), если вы переключите float на double в приведенном выше коде, вы устраните проблему!Может ли это быть оно?

Нет, вы просто откладываете решение этого вопроса.двойники по-прежнему демонстрируют ту же проблему, только с большими числами.

@ebel

думая об этом, у вас есть 64 бита, представляющие число, большее 2 ^ 64 (double.maxvalue), поэтому ожидается неточность.

2^64 - это не максимальное значение double.2^ 64 - это количество уникальных значений, которые может содержать double (или любой другой 64-разрядный тип). Double.MaxValue равно 1.79769313486232e308.

Неточность с числами с плавающей запятой возникает не из-за представления значений, превышающих Double.MaxValue (что невозможно, исключая Double.PositiveInfinity).Это связано с тем фактом, что желаемый диапазон значений просто слишком велик, чтобы вписаться в тип данных.Таким образом, мы отказываемся от точности в обмен на большую эффективную дальность действия.По сути, мы отбрасываем значащие цифры в обмен на больший диапазон показателей.

@DrPizza

Даже не;кодировки IEEE используют несколько кодировок для одних и тех же значений.В частности, NaN представлен показателем всех битов-1, а затем любым ненулевым значением для мантиссы.Таким образом, существует 252 NAN для парного разряда, 223 NAN для одиночного.

Верно.Я не учитывал повторяющиеся кодировки.На самом деле их 252-1 NaNs для парных и 223хотя для одиночек -1 NaNs.:p

2^64 - это не максимальное значение double.2^ 64 - это количество уникальных значений, которые может содержать double (или любой другой 64-разрядный тип).Double.MaxValue равно 1.79769313486232e308.

Даже не;кодировки IEEE используют несколько кодировок для одних и тех же значений.В частности, NaN представлен показателем всех битов-1, а затем Любой ненулевое значение для мантиссы.Таким образом, существует 252 NANS для парного разряда, 223 NANS для одиночек.

Верно.Я не учитывал повторяющиеся кодировки.Однако на самом деле существует 252-1 NAN для парного разряда и 223-1 NAN для одиночного.:p

Дох, забыл вычесть бесконечности.

Приблизительная версия этой проблемы, которую я узнал, заключается в том, что 32-разрядные числа с плавающей запятой дают вам 5 цифр точности, а 64-разрядные числа с плавающей запятой дают вам 15 цифр точности.Это, конечно, будет варьироваться в зависимости от того, как кодируются значения с плавающей точкой, но это довольно хорошая отправная точка.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top