Google Calculator Glitch, может ли быть плавающим против двойного быть возможной причиной? - PullRequest
4 голосов
/ 26 августа 2008

Я сделал это только для ударов (так что, не совсем вопрос, я могу видеть, что даудмодинг уже происходит), но вместо недавно найденной 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 в приведенном выше коде, вы исправите проблему! Может ли это быть так?

/ * т.пл. 1015 *

Ответы [ 7 ]

4 голосов
/ 26 августа 2008

Чтобы узнать больше о таких глупостях, см. Эту прекрасную статью, касающуюся калькулятора Windows.

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

Внутренности Калька - арифметика двигатель - был полностью выброшен и переписан с нуля. стандартная библиотека IEEE с плавающей точкой был заменен на арифметика произвольной точности библиотека. Это было сделано после того, как люди продолжал писать ха-ха статьи о том, как Calc не может сделать десятичную арифметику правильно, что например вычисление 10,21 - 10,2 - 0,0100000000000016.

2 голосов
/ 26 августа 2008

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

но это то, что должно быть:

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

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

2 голосов
/ 26 августа 2008

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

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

1 голос
/ 26 августа 2008

@ 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 для одиночных игр.

True. Я не учел дублирующиеся кодировки. Хотя на самом деле есть 2 52 -1 NaN для двойников и 2 23 -1 NaN для одиночек. : Р

0 голосов
/ 13 сентября 2008

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

0 голосов
/ 27 августа 2008

True. Я не учел дублирующиеся кодировки. Тем не менее, на самом деле есть 252-1 NaN для пар и 223-1 NaN для одиночных игр. : Р

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

0 голосов
/ 26 августа 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...