LINUX.ORG.RU

0.1 + 0.2 на x86

 , , ,


0

1

В конторе горе, у бухов не идут копейки. Хотя у нас всё работает нормально. Грешу на ошибки при работе с флоатами. Да да, дельфи, олап. Что вам скажет ваш x86 на 0.1 + 0.2? У меня - 0.30000000000000004
Немного оффтоп, но я не знаю куда пойти.

upd. код не мой, не надо писать, что я говнокодер и про bigdecimal/аналоги.

★★★★★

Последнее исправление: crutch_master (всего исправлений: 1)

Ответ на: комментарий от anonymous

0.30000000000000004
Плавающая точка почему так называется знаишь?

потому что «оно не тонет»? )))

Egor_
()

Что вам скажет ваш x86 на 0.1 + 0.2

Это ещё ерунда, поинтересуйся, как там с ассоциативностью дела.

0.1 + 0.2 + 0.3 это совсем не то, что 0.3 + 0.2 + 0.1

anonymous
()

Что вам скажет ваш x86 на 0.1 + 0.2?

Это несерьезно. Реальные пацаны ворочают миллиарды 1000000000.1 + 1000000000.2

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

64 бита на мантиссу для того, чтобы без ошибок округления представлять любое 64-х битное целое (т.е. вся целочисленная арифметика на флоатах будет совпадать с обычной). 16 на экспоненту, потому что на экспоненту в double приходится 11 бит, т.е. в один байт она не помещается. Бонусом идёт сильное уменьшение ошибок округления, потому что реально расчёты ведутся с бОльшей точностью, а округляются до double/float только результаты.

gremlin_the_red ★★★★★
()

у бухов не идут копейки

Грешу на ошибки при работе с флоатами.

Увольнять нахер!

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

это был специальный проц для точных вычислений

Это был специальный проц для быстрых вычислений с плавающей точкой. К 486, с ростом скорости, стали сказываться недостатки дизайна сопроцессора, плюс, к этому моменту транзисторов в основном процессоре стало настолько больше, что добавление ещё и сопроцессорных на себестоимости сказывалось незначительно, вот и реализовали x87 инструкции прямо в процессоре.

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

Это ещё ерунда, поинтересуйся, как там с ассоциативностью дела.

0.1 + 0.2 + 0.3 это совсем не то, что 0.3 + 0.2 + 0.1

Это коммутативность.

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

Это коммутативность

Да ну? А где здесь два элемента? Я вижу три.

Хорошо, запишем по-другому: (0.1+0.2)+0.3 != 0.1+(0.2+0.3)

Может тогда «знатоки» не будут херню пороть.

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

Да ну? А где здесь два элемента? Я вижу три.

Три – это два плюс один. Но суть в том, что у тебя они в разном порядке. Штука в том, что сложение и умножение в IEEE754 как раз таки коммутативны (т.е. a + b = b + 2). А вот с ассоциативностью проблемы, да.

hateyoufeel ★★★★★
()

ТЫ ЧТО, ДЕНЬГИ ФЛОАТАМИ СЧИТАЕШЬ????!! o_O

Harald ★★★★★
()
$ cat test.c
#include <stdio.h>

int
main(void)
{
	double a = 0.1;
	double b = 0.2;

	printf("%.04lf\n", a + b);
	printf("%.16lf\n", a + b);
	printf("%.32lf\n", a + b);
}
$ ./test
0.3000
0.3000000000000000
0.30000000000000004440892098500626

А что ещё ты ожидаешь увидеть?

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

Я написал

0.1 + 0.2 + 0.3 это совсем не то, что 0.3 + 0.2 + 0.1

(a+b)+c != a+(b+c)

это нарушение ассоциативности, при чем тут коммутативность? с коммутативностью проблем как раз нет, потому я и имел право раскрыть скобки как раскрыл, поменяв местами 0.2 и 0.3

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

ТС, выкинь float и используй decimal

Как вариант, хранить всё в целом числе копейками или какая у него там валюта, если decimal нету.

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

* Голосом Николая Дроздова * «Вы только посмотрите, с какой энергией извивается этот представитель anonymous lorus vulgaris»

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

Да куда бежать, везде карантин.

В IT все на удалёнку перешли, в нашу контору за карантин уже человек 10 разрабов новых взяли.

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

Например, поделить 100=00 рублей на 3 и опять помножить на 3 - получится 99=99

Можно извратиться и использовать какой-нибудь rational-тип.

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

Это не будет соответствовать правилам бухгалтерии и они всё равно огорчатся. У них обычно нужно чтобы было как на калькуляторе, при этом количество знаков для округления и порядок вычислений прописаны в самом алгоритме. Думается, автор темы имеет дело с какой-то багой.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)

у бухов не идут копейки Да да, дельфи, олап

Надо было писать на КОБОЛе. А ещё лучше на ЛИСПе

[1]> (+ 0.1 0.2)
0.3
[2]> (= 0.3 (+ 0.1 0.2))
T
no-such-file ★★★★★
()
Ответ на: комментарий от dimgel

Хранить деньги во float - ламерство.

Да. Хотя считать бывает удобнее во float.

Для этого есть спец. типы (Decimal, BigDecimal, типа того), не теряющие точность.

Мои две копейки: в Visual Basic был тип Currency.

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

спец. типы (Decimal, BigDecimal, типа того), не теряющие точность

сколько будет, если 2 копейки умножить на 1% процент?

  • Сколько стоит капля пива? - Ноль. - Тогда накапете мне 2 литра пива.
anonymous
()
Ответ на: комментарий от anonymous

сколько будет, если 2 копейки умножить на 1% процент?

Попытка поймать на такой примитивный вопрос - тоже признак ламерства. Ты никогда с BigDecimal не работал? А если тебе такое нужно выполнять и держать в базе, то надо заранее озаботиться резервированием должного количества знаков после запятой.

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

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

… еще сколько знаков перед запятой, округление и еще-хрен-знает-что.

И всё равно остается вопрос «сколько стоит накапать крушку пива?» Как там с «сохранением точности» в операциях.

Упустим про «точность» предсталения дробей(деления) - 1/3, 1/6, 1/7, 1/9.

Может надо начать считать погрешности, устроит в бухгалтерии физическую лабораторию? И будут у нас финансовые новости типа «ВВП выросло на 1,2% ± 5,5%».

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

Мсье с бухгалтерией дел похоже не имел, вот и фантазирует. Правила округления там простые и между прочим законодательно закреплённые. Это во-первых.

А во-вторых, что-то я не припомню чтобы бухгалтерам приходилось делить на 3, 7, 9 и т.п. В голову приходит только расчёт процентов (для уплаты налогов и т.п.), но тут см. во-первых.

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

не теряющие точность

бухгалтерия

Хорошо виляешь лохматым хвостом.

Бухгалтерия бывает разная. Отчет в налоговую - это еще один этап в «потере точности».

я не припомню чтобы бухгалтерам приходилось делить на 3, 7, 9

Везет знакомым тебе бухгатерам.

anonymous
()

пыхожысерам не понять, т.к. про decimal они не слышали

lovesan ★★
()

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

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

Как вариант, хранить всё в целом числе копейками или какая у него там валюта, если decimal нету.

Да нету там возможности поменять тип, говнокод не мой. Я знаю, как работают флоаты, сталкивался с косяком, когда на x86 и x64 получалось разное.

crutch_master ★★★★★
() автор топика

Ахахахахахах ЛОЛ, буквально года три четыре назад я тоже тут позорился аналогичным образом, кажется в Python дело было )))))

Выход - подсчет используя отдельный int для копеек или дробных частей. Либо может специальный класс соорудить для таких операций, который будет следить за точностью при разных действиях. Если работа в Python использовать large int, если в C++, то быть может есть готовые решения кажется я слышал о таковых

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 3)
Ответ на: комментарий от I-Love-Microsoft

Ахахахахахах ЛОЛ, буквально года три четыре назад я тоже тут позорился аналогичным образом, кажется в Python дело было )

Да не мой это код:) Есть говно без сорцов, которое считает флоаты через жопу, надо или что-то сделать, чтобы оно заработало, или найти крайнего.
Технически - это всё вендопроблемы. Если бы это был мой код, я бы даже на форум с таким не полез.

crutch_master ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

в третьем питоне все числа это bignum

anonymous
()
Ответ на: комментарий от I-Love-Microsoft

Или Wine хотя бы в режиме win2000

А это идея, попробовать можно.

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

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

crutch_master ★★★★★
() автор топика

Короче выяснили. На шиндовсе хп почему-то используется float вместо double со всеми вытекающими в виде ошибок уже на 7-ой цифре. Пойду к дельфистам.

crutch_master ★★★★★
() автор топика

не надо писать, что я говнокодер и про bigdecimal/аналоги.

Надо Вася, надо!

p.s. А что мешает взять bigdecimal?

AntonyRF ★★★★
()
Последнее исправление: AntonyRF (всего исправлений: 1)

У нас на работе есть жирный проект в project. Там сводятся человеко-часы + какие-то цены. В 2010 project сумма правильная, а в 2013 project получается разница что-то там в 104р с копейками. Непонятно откуда вообще это вылезает. Так что говнокод он везде.

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

p.s. А что мешает взять bigdecimal?

Что автору pivotcube мешало это сделать в конце нулевых? Не знаю, напишу ему завтра.

crutch_master ★★★★★
() автор топика

флоатами

Да да, дельфи

Я бы начал с пояснения, какой именно флоат. В паскале есть несколько вещественных типов, есть общепринятые типа double, есть свой шестибайтовый велосипед real.

P.S. А, уже нашёл:

На шиндовсе хп почему-то используется float вместо double со всеми вытекающими в виде ошибок уже на 7-ой цифре.

Ну тоды да, их косяк. Я когда на паскале математику писал, на double спрыгнул очень быстро (и это была где-то середина 90-х).

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

Олап компоненты платные, закрытые и никто в их кишки не залезет.

Ну тогда надо делать простейший контрольный пример, на котором ошибка вылезает, и пинать их ТП, если вы их покупали. Да, выглядит не очень реально, но в данной ситуации все остальные пути — ещё менее реальны, ИМХО.

Кстати, есть вероятность, что тестовый пример может помочь, даже если до ТП не дойдёт. :)

P.S. Скорее всего, этот комментарий уже неактуален, но не удаляю пока на случай, если замена float на double не поможет.

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

Короче там либа была с float'ом. Подменили на нормальную и всё заработало. По воле случая нормальные либы были в нашем отделе на семёрках, а у всех остальных - корявые и не у кого семёрок не было.

crutch_master ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.