Pull to refresh

Comments 121

У меня все использование гуглокалькулятора ограничилось вычислением количества попугаев в удаве.
а я метрические величины перевожу =)
UFO just landed and posted this here
А как-же вычислить погрешность при использовании попугаев?
Раз и Два
Удобно деньги конвертировать. Не надо делать лишних действий типа выяснения текущего курса.
Удобно только для оценочных представлений. По факту гугловый курс далек от истины.
Разве? У меня Гугл и ЦБР дают одинаковые данные с точностью до четвёртого знака…
Хорошо, если для России это работает, но я из Украины и недавно переводил евро в гривны. Гугл выдал какой-то заоблачно-задранный курс, которому даже приблизительного подтверждения я не нашел ни в одном официальном источнике.
Используйте тот же Центробанковский курс. Проблем-то. Там прямо в результатах есть ссылка на объяснения. Citi, похоже, Украина интересует ещё меньше чем Россия, но на ЦБР и гривна и тенге торгуются ежедневно.
Я пытался переводить UAH в RUB, но курс какой-то не такой
А вы попробуйте этот обмен где-нибудь в Нью-Йорке осуществить IRL — ещё и не такой курс увидите. Но если Гуглу малость намекнуть
Ага, проценты по кредиту.
Проверил — действительно так. Ох, не зря многие не верили бесовским машинкам! Деньги всегда только в уме пересчитывать! ;)

Я вот люблю чеки поперепроверять, когда подозрительно много денег =).
Для пересчета денег обычно используют специальный тип — Decimal с фиксированной точкой и заданной (максимальной) длинной части до запятой, после запятой и четко указанным способом округления (вниз, вверх, до ближайшего вниз, до ближайшего вверх...)
Ну, лишний рубль для триллионера это… скажем так, некритично:)

Однако могли бы и строковый алгоритм реализовать для арифметических операций, с неограниченной длиной строк:

50 000 000 000 000 000 000 000 000 000 000 000 000 000 — 50 000 000 000 000 000 000 000 000 000 = 5.0 × 10^40, хотя юзер скорее ожидает увидеть 49 999 999 999 950 000 000 000 000 000 000 000 000 000
Вроде скоро новый ролик выходит. Называется «Математическая магия».
Кстати, интересно, насколько денег каждый день обманывают Билла Гейтса, когда пересчитывают проценты на его сумасшедших суммах вкладов? :)
Это он так вам пытается сказать, что живой)))
ну, это явление старше гугла: погрешность при конвертации между различными системами счисления. А такая конвертация происходит для нас неявно, в компьютерах используется 16-ричная и двоичная системы.
Эту погрешность можно заметить не только не больших числах, но и любых других,
вот, пример в копилку 5.000000000000000002 — 5.000000000000000001 = 0
вот, примерно по теме:
xpoint.ru/know-how/Articles/FloatingPointNumbers#OtkudaBeryotsyaNetochnost'
По-моему вы абсолютно не понимаете, что вы пишете. :) В топике идет речь про целые числа.
Покурите floating point, что ли, на хабре была статья про них сполгода назад.
Как по-вашиму представляются большие целые числа в компьютере? Представляются они в формате с плавающей точкой. Да ещё и в двичной системе. Разрядная сетка матиссы ограничена вот и происхояд всякие чудеса.
Пример:
12 345 678 123 456 781 234 567 812 345 678 + 0 = 1.23456781 × 1031
Внимание вопрос — сколько дейсвительных разрядов в результате, потерялась ли точность и чем она ограничена?
Хм. А по-вашему что? GMP уже умер?
bash-3.1$ clisp

Copyright © Bruno Haible, Michael Stoll 1992, 1993
Copyright © Bruno Haible, Marcus Daniels 1994-1997
Copyright © Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright © Bruno Haible, Sam Steingold 1999-2000
Copyright © Sam Steingold, Bruno Haible 2001-2006

[1]> (- 500000000000002 500000000000001)
1

Вроде неплохо так считает. И точность не теряется ;-)

P.S. Хотел привести пример с (! 12345) но боюсь меня закидают камнями за 40Кб циферек :-D
Декаинарная система счисления используется в компьютера в таком-же объеме, как и гексаинарная. А вопрос тут не в конвертации между раздичными системами счисления, а в методе представления числа с плавающей точкой в памяти.

И, кстати, сомневаюсь я, что инженеры Google не могут выяснить в чем проблема. Думаю, они поняли это сразу, как им о ней сообщили. Также, думаю, они знали, что эта проблема существует, и до этого. При разработке любой системы, работающей с числами с плавающей точкой заранее выбирается такой необходимая точность, в связи с чем выбирается представление. Единственное решение такой проблемы — использование BIGNUM-ов., это представление дает практически неограниченную максимальную точность.
UFO just landed and posted this here
о_О Вас ничему в школе не учили?
UFO just landed and posted this here
rtfm: ru.wikipedia.org/wiki/Числа_с_плавающей_запятой#.C2.AB.D0.9F.D0.BB.D0.B0.D0.B2.D0.B0.D1.8E.D1.89.D0.B0.D1.8F_.D0.B7.D0.B0.D0.BF.D1.8F.D1.82.D0.B0.D1.8F.C2.BB_.D0.B8_.C2.AB.D0.BF.D0.BB.D0.B0.D0.B2.D0.B0.D1.8E.D1.89.D0.B0.D1.8F_.D1.82.D0.BE.D1.87.D0.BA.D0.B0.C2.BB
UFO just landed and posted this here
UFO just landed and posted this here
Если уже калькировать, то децимальная и гексадецимальная:)
UFO just landed and posted this here
А Excel нормально такие суммы обсчитывает? А OpenOffice.org? Всё-таки Google Calc редко используют для финансовых рассчётов, а Excel я у бухгалтеров частенько открытым замечал…
Думаю с такой неточность никто не раззорится :-)
UFO just landed and posted this here
Excel помнится не умел умножать 850 на 77.1
help.wugnet.com/office/Bug-Excel-2007-ftopict1019180.html
=)
Все-таки некоторые программы должны оставаться десктопными… а еще лучше использовать обычный калькулятор
у обычных калькуляторов регистры тоже не резиновые, без погрешностей на больших числах никуда
Да, но у Google дело не в регистрах. Я подозреваю, что Google делает ошибку, когда использует БПФ при работе с «длинной арифметикой».
Если до всего докапываться, то везде найдёте ошибки)))
Просто у кого-то слишком много свободного времени :)
Внутри используют какой-нибудь тип с мантиссой и эскпонентой, и после операции точность теряется.
Думается мне, что они используют старый добрый способ сложения чисел: перекатать два числа в строку и поразрядно (по сути — «попозицинно», т.к. проходим по строке или массиву) выполнять операции с ними.
машинная арифметика:) ох, помнится, на втором курсе товарищ Довгий нас с этим гонял. сложение это ещё что, вот умножение и деление — совсем страх
А как это у вас на картинке гугль по запросу
«200 000 000 000 002 — 200 000 000 000 001»

считает
«500 000 000 000 002 — 500 000 000 000 001»?

Дух какого бога двойку на пятерку подменил?)
вначале посчитали 500 000 000 000 002 — 500 000 000 000 001, нажали Search, а после вписали 200 000 000 000 002 — 200 000 000 000 001 и сделали скриншот. никакого фотошопа
«Опытном путём удалось установить, что проблемы именно с этой операцией у калькулятора начинаются после 333 трлн.» — у чуваков много свободого времени (;
казалось бы, точная граница находится за логарифм операций. в переводе на русский, на таких числах времени нужно совсем немного. :)
Думаю, они искали скриптом. А там времени надо не больше нескольких минут, наверное. Плюс нужен заведомо правильно считающий такие числа калькулятор и максимум полчаса(это если просто сдирать с примера) кодинга.
Некто, даже умудрился воспроизвести этот баг на Си.
    #include <stdio.h>
    #include <math.h>

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

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

       printf("da = %f,  db = %f\n", da, db); // para ver como se almacenan los numeros
     
       printf("%s - %s = %f\n", a, b, da-db);
      
       a = "500000000000002";
       b = "500000000000001";
       da = atof(a);
       db = atof(b);

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

Вот и верь теперь компьютерам…
UFO just landed and posted this here
UFO just landed and posted this here
Потому как L. Если я не ошибаюсь, питон использует для L длинную арифметику с числами нефиксированого размера (вместо стандартных 32, 64бит).
UFO just landed and posted this here
a и b суть числа с плавающей точкой, а у них, как известно, ограничено количество значащих цифр. Подозреваю, что единичка и двоечка просто не влезли.
можно переписать, и все работает:
#include <stdio.h>
#include <math.h>

int main()
{
  unsigned long long la = 399999999999999LL;
  unsigned long long lb = 399999999999998LL;

  printf("sizeof(int) = %d, sizeof(long) = %d, sizeof(long long) = %d\n", 
          sizeof(int), sizeof(long), sizeof(long long));

  printf("la = %lld,  lb = %lld\n", la, lb); 

  printf(" = %lld\n",  la - lb);

  la = 500000000000002LL;
  lb = 500000000000001LL;

  printf("la = %lld,  lb = %lld\n", la, lb);
  printf(" = %lld\n", la - lb);

  return 0;
}

-----
la = 399999999999999,  lb = 399999999999998
 = 1
la = 500000000000002,  lb = 500000000000001
 = 1
Пример годится только для целых. Без преобразования (atof, strtod) для дробных (и приведенных целых) лучше так:
#include <stdio.h>
#include <math.h>

int main()
{
        double a = 500000000000002.0;
        double b = 500000000000001.0;

        printf("%lf - %lf = %lf\n", a, b, a - b);

        return 0;
}
----
500000000000002.000000 - 500000000000001.000000 = 1.000000
за такой код расстреливать надо
вполне нормальный код. Просто вы бы сделали по-другому, и конечно же лучше =)
это кривой код, и он не будет работать, тут даже компилировать не надо. Начиная с того, что 399999999999998 банально не влезет во float, продолжая преобразованием double->float и заканчивая выводом вовсе не чисел, полученных после atof(), а исходных строк. Если бы автор вывел числа вот так

printf(«%f — %f = %f\n», da, db, da-db);

он бы увидел одну странность :)
хотя он там выводит числа da и db… Такое чувство, что он на них даже не смотрел :)
Всё логично, этот код про то, как могла возникнуть такая ошибка: преобразованием atof, неверным типом float и т.п.
Беда лишь в том, что во float не влезет и меньшее число, а double может обработать гораздо большее. Т.е. ошибка в чем-то другом.
UFO just landed and posted this here
ничего особенного, неужели никто не читал про накопление погрешностей при вычислениях с числами в двоичном представлении?
а в нормальных финансовых системах не используют алгоритмы, дающие такие погрешности.
Там представление числа десятичное, что медленнее, зато надежнее. Если я правильно помню, то у небезызвестного товарища Д.Кнута много внимания алгоритмам выполнения арифметических операций уделяется.
Видимо потому что у вас не совсем верно все описано
Система счисления роли не играет, всегда будут проблемы. Значение 1/3, например, нельзя точно представить в десятичной системе, а в троичной возможно.
5 000 000 000 005 000 001 — 503 000 000 000 000 000 = 4.49700 × 1018

5 000 000 000 005 000 001 — 503 000 000 000 000 000 = 4.49700 × 10^18
А вот это уже странно)) Как-то не по-алгебраически))
UFO just landed and posted this here
Большие числа переводятся в float, который состоит из двух частей — числовой компоненты и порядка. Числовая компонента имеет ограничение по точности, получающееся из-за ее фиксированного размера
То есть для операций с внешним долгом США калькулятор Гугла не подходит :-)
Это делается с целью, что бы люди одумались — там же видно что разница в 1! а ты полезв калькулятор считать)
UFO just landed and posted this here
придется теперь доход на другом сайте подсчитывать…
вот что называется пытливый ум))))))))))))
Проверил на Парсере:

$iTest(500000000000002-500000000000001)

$iTest = 1
По хорошему надо делать две переменных и вычитать одну из другой, а то твоё вычитание происходит на этапе прекомпиляции (или как там это у Парсера) и во время выполнения уже никакого вычитания не происходит — просто присваивается значиние переменной.

Вот пример на PHP, который выводит 1
<?php
$a = 500000000000002;
$b = 500000000000001;
echo $a - $b; 
?>
Проверил :)

$iIntA(500000000000002)
$iIntB(500000000000001)

$iTest($iIntA — $iIntB) == 1
вот объясни ты зачем такие большие цифры считаешь? такое чувство что чем то не очень легальным занимаещся: о)
либо прирожденный тестер либо просто чтобы «позырить» :)
ни тестер а тостер: о)
я надеюсь что ученые из СERN'а погрешность Большого адронного коллайдера не на Гуугловском калькуляторе считали о_О
Вы такими темпами скоро Гугл — сломаете! :)
Не думал гугл, что народ будет нефть попугаями мерить :)
На картинке в поле нарисовано 200....2-200....1, а в ответе 500....2-500....1=0
Совсем плохой калькулятор…
За что люблю Ruby — там такой херни не наблюдается.
Что, всегда бигнамы используются? Этож сколько он должен памяти жрать, если большими числами оперировать…
интересно, а как дела с другими операциями?
Вот у вас времени вагон! Вашу бы энергию, да в нужное русло!
Вот вам классический баг. Пользователю неведомы ограничения 32- или 64-разрядности. Если ему предоставляется возможность ввести числовое выражение из, скажем, 256 символов, то будьте добры обеспечить соответствующую их обработку как массивов строк. Вряд ли юзеры так злоупотребляют гуглокалькулятором, чтобы подвесить серверы посимвольным сложением-вычитанием «в столбик». Гугл мапс намного больше жрет.
чтобы соблюсти «любовь к математике» — считайте все в 2-чной системе и все получится :)
Программа без ошибок — не программа ;-)

«Количество акций во время IPO соответствовало константе “e”» — ээмммм, как так?))
Иррациональные акции дробились и размножались, что непонятного? = )
По-моему проблемы с арифметикой не у Гугла, а у того кто из 500000000000002 вычитает 500000000000001 на калькуляторе :)
Вот ещё классический кусочек кода, тоже про ошибки при вычислениях:
double val = 0.00;
for (int i = 0; i < 10; ++i) val += 0.10;
Response.Write(val == 1);
Странно это, очень странно. Казалось бы логичным написать этот калькулятор вне привязки к машинным представлениям чисел, т.е. тупо — производя все операции поразрядно в соответствующей системе исчисления и храня числа в виде строк, как это делается в приложениях, производящих расчеты с денежными суммами. Ибо в этом случае никакого ограничения по величине чисел, входящих в арифметические выражения, нет. Не так быстро работает, конечно, но в том-то и дело, что подобные расчеты нужны, чаще всего, в небольших количествах.
Лежал, перед сном читал документацию и тут developer.mozilla.org/En/A_re-introduction_to_JavaScript#Numbers тоже нашел упоминание о различных интересных эффектах в арифметике JS.
Скорее не в арифметике самого JS, а в какой-либо имплементации.

Это и не так важно. Важно то, что в большинстве используемых сейчас браузеров есть этот эффект.
Попробуйте сложить 0.1 и 0.2 в IE, мозилле, опере и сафари.

Вот вам и это 64-битный IEEE-формат. В PHP и еще много где тоже наблюдаются различные эффекты по этому поводу.
вот так вот плагиатят новости с хабрахабра: _ttp://www.3dnews.ru/software-news/kalkulyator_google_oshibaetsya/

=\
эй, а почему вы говорите, что вычитаете 500 000 000 000 001, а в строке ввода написано 200000000000001 ??
Количество акций во время IPO соответствовало константе “e”…

My gosh, по мнению автора было выпущено всего 2 целых 71 сотая акций???
Vertexodessa > вначале посчитали 500 000 000 000 002 — 500 000 000 000 001, нажали Search, а после вписали 200 000 000 000 002 — 200 000 000 000 001 и сделали скриншот.
Археология жить мешает?
Sign up to leave a comment.

Articles