LINUX.ORG.RU
ФорумTalks

Объясните, что же не так с представлением чисел в памяти

 


0

1

Привет. Я читал что из-за сложностей преобразования из десятичной системы в двоичную возникают погрешности и другие странности, вроде отрицательного нуля или х*2=inf, а так-же, что размер числа ограничен размером машинного слова.

И может быть это всё нормально, но мне это кажется странным.

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

А раз так, то float можно хранить как число с фиксированной точкой (правда, я читал что так погрешность даже выше, но наверное это опечатка), причём положение точки будет храниться отдельно и для операции над двумя числами они будут преобразовываться в дроби с одинаковой длиной дробной части.

Я понимаю, это ресурсозатратно, но ведь это же необходимая жертва?

IEEE754 — это жирное legacy, от которого хрен избавишься.

hateyoufeel ★★★★★ ()

Гугли bigmath, bigfloat, bigdecimal и тому подобное.

i-rinat ★★★★★ ()

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

Я понимаю, это ресурсозатратно, но ведь это же необходимая жертва?

Давно есть модули, либы и прочие программные надстройки для записи числа например в строку и для последующих арифметических операций с ними. На отдельно взятой улице можно реализовать хоть левостороннее, хоть зигзаговое движение, а за её пределами так двигаться не получится. ЯП подстраиваются под возможности процессоров, а там таких чисел нету. Либы написанные на этих ЯП работают с типами данных имеющимися в них, и новые типы туда добавлять очень тяжело. Одно цепляется за другое, и длинные числа за пределы среды их обитания вытаскивать коряво.

Napilnik ★★★★★ ()

Узнай, пожалуйста, про GNU MP, mpfr/mpfc

unanimous ★★★★★ ()

это ресурсозатратно

Да.

это же необходимая жертва

Нет.

/thread

redgremlin ★★★★★ ()

положение точки будет храниться отдельно

Это как-то отличается от т.н. «экспоненты»?

вроде отрицательного нуля

Это, разве, не специально добавленное полезное свойство?

не вижу преград для разбиения числа на части и хранения его в нескольких словах

Их ровно 2: ресурсы. Сколько памяти/процессора ты готов выделить для вычисления длинны окружности, описанной вокруг квадрата со стороной=1 ?

DonkeyHot ★★★★★ ()
Ответ на: комментарий от hateyoufeel

А, гм, на что ты предлагаешь переходить? bigdecimal и подобное? Оно же жутко медленное.

catap ★★★★★ ()

Там всё должно быть нормально.

но ведь это же необходимая жертва?

Нет. Ещё Крис Касперски писал, что x86 процы спроектированы максимально криво. Это означает, что потери начинались с проца, а потом уже стали криво писать программы. В идеале все программы могут работать в 3-5 раз быстрее, но это никому не выгодно...

xwicked ★★ ()
Ответ на: комментарий от catap

Java вообще нельзя юзать без bigdecimal. Видишь в коде double — разработчик джун.

Deleted ()
Ответ на: комментарий от xwicked

но это никому не выгодно...

Нифигасе не выгодно, как минимум бы если так все просто, нашлись бы молодые, зубастые, которые бы выгрызли себе долю рынка за счет «прямых» процессоров. Тем более сейчас уже далеко не винтеловские времена, скомпилировать под что-то новое готовы даже крупные софтопроизводители.

praseodim ★★★★ ()
Последнее исправление: praseodim (всего исправлений: 1)
Ответ на: комментарий от praseodim

ты предлагаешь запилить процы с аппаратной поддержкой больших чисел?

Harald ★★★★★ ()
Ответ на: комментарий от Deleted

Угу, а потом оказывается что 4.3% процента от времени работы приложения жрет сериализация в Json ибо библиотеку писали солидные господа и они для сериализации double в json использовали BigDecimal.

Так вот, почему нельзя использовать double в java? Мне правда интересно.

catap ★★★★★ ()
Ответ на: комментарий от Harald

Нет, я о том, что современные процессоры x86 при всей их вроде кривости на самом деле до предела оптимизированные под универсальное применение. Настолько, что уже баги в безопасности стали вылезать, исправление которых понижает их скорость.

Попытки кого-то оказаться лучше как-то сдуваются. Если нужна универсальность рулит и педалит таки x86.

К примеру, сколько с ARM носятся, одно время даже хостеры стали vps на arm предлагать, ноуты на arm - и что-то «не взлетает», даже наоборот мода на vps и ноуты-арм стала проходить толком не начавшись. В тоже время, у них все-таки есть своя ниша на планшетах, смартфонах и подобных устройствах.

А если нужно до предела ускорить какую-то конкретную задачу давно уже научились делать процы специально под нее. К примеру асики для биткоинов.

praseodim ★★★★ ()
Ответ на: комментарий от catap

Свои фантазии можешь оставить там, откуда пришел.

И прочти уже javadoc, не позорься. Интересно ему.

Deleted ()
Ответ на: комментарий от Harald

Так были они же. Никому оказались не нужны на практике.

И в каком-то современном проце есть встроенная поддержка decimal, что позволяет достаточно просто организовать decimal произвольной длины программно. Кажется, у IBM.

i-rinat ★★★★★ ()
Ответ на: комментарий от Deleted

Java вообще нельзя юзать

На этом, пожалуй, остановимся

buddhist ★★★★★ ()
Ответ на: комментарий от i-rinat

И в каком-то современном проце есть встроенная поддержка decimal, что позволяет достаточно просто организовать decimal произвольной длины программно. Кажется, у IBM.

Встроенная поддержка decimal «куплена из совка»: «В 1967 году на выставке в Лондоне, где демонстрировалась “МИР-1”, она была куплена американской фирмой IBM - крупнейшей в США, являющейся поставщиком почти 80% вычислительной техники для всего капиталистического мира. Это была первая (и, к сожалению, последняя) покупка советской электронной машины американской кампанией» ©.

quickquest ★★★★★ ()

Я не вижу преград

чтобы потом считать в несколько заходов

Т.е. в несколько раз медленнее. А так-то всё уже давно изобретено и когда нужно используется.

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Да если бы только медленнее. Атомарных операций для bigdecimal чисел как бы нет, и это большая боль.

catap ★★★★★ ()
Ответ на: комментарий от xwicked

В подтверждении своих слов:

У нас в стране мы фактически вынуждены быть монополистами — никто все равно, кроме нас, не может сделать совместимый процессор. Это очень трудно — если прочтете все документы, все равно работать как надо не будет. Мы же знаем все закоулки, причем двух архитектур — Intel х86 и SPARC. Intel, кстати — очень сложная архитектура, потому что, как я все время шучу, она была не разработана, она «случилась». Там мусора, еще с 88-й модели — знаете сколько слоев? Изучить этот весь мусор — ну никак не меньше трех лет, а все документы, что публикуются, очень мутно составлены. Пока мы единственные в стране, кто умеет делать Intel-совместимые процессоры.

Из интервью Бориса Бабаяна, главного архитектора наших процессоров. По-моему шикарно! Я ещё читал инфу или в этой или в другой статье, что в наших процах нет погрешности вычислений с плавающей точкой.

xwicked ★★ ()
Последнее исправление: xwicked (всего исправлений: 1)
Ответ на: комментарий от catap

Я не предлагаю. Но есть, например, ubox. Правда, я понятия не имею, есть ли реализации и насколько они корректны. Я только статью и презентацию видел когда-то.

hateyoufeel ★★★★★ ()

Объясните, что же не так с представлением чисел в памяти

Все с ним так, в рамках ущербности самой идеи. =)

Я понимаю, это ресурсозатратно,

Не уверен, что понимаешь, насколько.

но ведь это же необходимая жертва?

Необходимая жертва чтобы что? Думаешь от впятеро более длинного float у тебя 0.1 + 0.1 вдруг станет равен 0.2?

t184256 ★★★★★ ()
Ответ на: комментарий от cvs-255

Вычисления с double и float в java попросту приводят к неправильным результатам и неправильно округляются. Для сравнения надо использовать что-то типа

if (Math.abs(a - b) > 0.00001)

Потому что == с ними не работает. Я работаю с финансами и просто выкинул эти вещи из своего поля зрения. Если ты сеньор жавист (а не локалхост энтузиаст), для тебя это прописная истина: float & double is evil.

ps: люди из нулевых думают, что создание объекта в java дорого. Это уже давно не так.

Deleted ()
Последнее исправление: rj45 (всего исправлений: 2)
Ответ на: комментарий от Deleted

Что значит неправильно округляются? Они округляются в соответствии с IEEE754. Точность представления вещественных чисел в компьютерах ограничена.

Или они где-то не по стандарту округляются?

В питоне вон тоже 2.0 - 1.1 = 0.8999999999999999. причина та же самая

cvs-255 ★★★★★ ()
Последнее исправление: cvs-255 (всего исправлений: 4)
Ответ на: комментарий от quickquest

Встроенная поддержка decimal «куплена из совка»: «В 1967 году на выставке в Лондоне, где демонстрировалась “МИР-1”

1. «The IBM 1401 is a variable wordlength decimal computer that was announced by IBM on October 5, 1959» ©

2. «В 1968 году машина МИР модернизирована и получила название МИР-1» ©

Уууупс.

redgremlin ★★★★★ ()
Ответ на: комментарий от cvs-255

Если ты вкурсе про IEEE754, ты не будешь задавать вопрос «что плохого в double».

Джуны любят Math.round() и хаки типа n / 100.0 * 100.0 для округления до энного числа после запятой. Это все приводит к неочевидным, но вполне реальным ошибкам в вычислениях.

В 100% случаев в java надо создавать BigDecimal, если не хочешь выстрелить себе в ногу.

зы: и хуже всего то, что в вузах об этом не рассказывают

Deleted ()
Последнее исправление: rj45 (всего исправлений: 1)
Ответ на: комментарий от Deleted

Я работаю с финансами и просто выкинул эти вещи из своего поля зрения.

не все работают с финансами в жабе

Harald ★★★★★ ()
Ответ на: комментарий от cvs-255

Проведи сравнение bigdecimal с double. На сколько наносекунд оно затормозится?

Deleted ()
Ответ на: комментарий от xwicked

в наших процах нет погрешности вычислений с плавающей точкой

Facepalm. Погрешность — она не от процессора зависит (ну ладно, fdiv bug никто не отменял, но shit happens, это чисто инженерный косяк) и страны его производства, а от неумолимых законов математики.

redgremlin ★★★★★ ()
Ответ на: комментарий от Harald

Не только финансы. Любые более-менее серьезные вычисления с плавающей точкой.

Deleted ()
Ответ на: комментарий от Deleted

Разве в вузах теперь не рассказывают, как числа хранятся в памяти?

cvs-255 ★★★★★ ()
Ответ на: комментарий от cvs-255

Инженерам может быть. Но там и не используют яву, они пишут на сях и плюсах. На теор. специальностях или не рассказывют или очень бегло. Не бьют по рукам при попытке использовать Math.round() и не раскрывают страшной тайны космических ошибок.

Deleted ()
Ответ на: комментарий от Deleted

Кто-то к примеру пишет игровые движки на жабе с вычислениями не в float/double? И чтоб оно работало, не тормозило и даже продавалось?

Harald ★★★★★ ()
Ответ на: комментарий от Harald

А ты их код читал? Уверен, что там именно голые float/double? Если уж гоняются за скоростью, скорее всего делают свои обертки. Как плюсовики на каждый класс делают свой в больших проектах.

Deleted ()
Ответ на: комментарий от Deleted

Проблема с double - отнюдь не java-специфичная. Она есть в любом ЯП, где есть double.

Я учился вообще на физическом факультете, но у нас было программирование небольшим курсом, и даже там успели рассказать про то, как double устроен в памяти, мантисса там, экспонента.

cvs-255 ★★★★★ ()
Ответ на: комментарий от Deleted

нуу, видеокарты, математический сопроцессор и SIMD инструкции жабий BigDecimal точно не умеют, так что куда им деваться

Harald ★★★★★ ()
Ответ на: комментарий от cvs-255

Проблема с double - отнюдь не java-специфичная.

Знаю, но я здесь про яву говорил.

Я учился вообще на физическом факультете

Инженерам значит рассказывают. А я на CS учился (теор. математика), нам не говорили про особенности имплементаций.

Deleted ()
Ответ на: комментарий от Deleted

Как плюсовики на каждый класс делают свой в больших проектах.

Лолчто?

cvs-255 ★★★★★ ()
Ответ на: комментарий от Deleted

нам не говорили про особенности имплементаций.

а прочитать самому кто-то запрещал

Harald ★★★★★ ()
Ответ на: комментарий от Deleted

Вам не говорили, что на хранение числа в double отводятся столько-то бит и поэтому операции с double имеют погрешность?

cvs-255 ★★★★★ ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)