Re[3]: Округление с помощью ceil...
От: Аноним  
Дата: 18.10.06 05:57
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, np9mi7, Вы писали:


N>>Здравствуйте, -Cheese-, Вы писали:


C>>>Я понимаю, что типа хранение чисел с плавающей точкой и всё такое... но как избежать этого?


N>>Например использовать целочисленую арифметику до самого последнего момента;


C>>>Получаем:

C>>>z1=4053.0000000
C>>>z2=4052.0000000

N>>А что должны получить?

C>4052.0000000

C>Объясняю смысл проблемы...

C>есть некоторые платежи для человека в некоторой валюте ,
C>например
C>1) 5.09
C>2) 31.091
C>3) 1.01
C>......

C>и есть итоговая сумма — например: 37.191

C>но с человека нужно брать в этом случае 37.20 = ceil(sum(x_i)), x_i — i-тый платёж

C>на может сложиться ситуация когда человек должен заплатить например ровно 12 у.е.,

C>а ceil(sum(x_i)) может равняться 12.01 у.е., что не есть хорошо...

Где только вас учили метематике!!
Простейшее округление делается так:
E — поправочный коэффициент = 0.5
M — множитель равный 10 в степени N(где N количество знаков после запятой)
S — число которое нужно округлить.

R — результат.
R = (floor(S * M + E)) * M, либо
R = (ceil(S * M — E)) * M
Re[4]: Округление с помощью ceil...
От: -Cheese-  
Дата: 18.10.06 06:17
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Где только вас учили метематике!!

А>Простейшее округление делается так:
А>E — поправочный коэффициент = 0.5
А>M — множитель равный 10 в степени N(где N количество знаков после запятой)
А>S — число которое нужно округлить.

А>R — результат.

А>R = (floor(S * M + E)) * M, либо
А>R = (ceil(S * M — E)) * M

Где меня только не учили математике... последний раз меня подучили на работе.
А ещё есть ТЗ, где ясно сказано, что даже при E=0.000000000000000000000000000000000000000001
результат округления x+E будет x+1, где х принадлежит множеству целых неотрицательных чисел (в данном случае)...
вот
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Округление с помощью ceil...
От: Аноним  
Дата: 18.10.06 06:35
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, <Аноним>, Вы писали:


А>>Где только вас учили метематике!!

А>>Простейшее округление делается так:
А>>E — поправочный коэффициент = 0.5
А>>M — множитель равный 10 в степени N(где N количество знаков после запятой)
А>>S — число которое нужно округлить.

А>>R — результат.

А>>R = (floor(S * M + E)) * M, либо
А>>R = (ceil(S * M — E)) * M

C>Где меня только не учили математике... последний раз меня подучили на работе.

C>А ещё есть ТЗ, где ясно сказано, что даже при E=0.000000000000000000000000000000000000000001
C>результат округления x+E будет x+1, где х принадлежит множеству целых неотрицательных чисел (в данном случае)...
C>вот

Опечатался. Вот так будет правильно.
R = (floor(S * M + E)) / M, либо
R = (ceil(S * M — E)) / M

Вы в нулях не ошиблись случаем?
Re[9]: Округление с помощью ceil...
От: np9mi7 Россия  
Дата: 18.10.06 06:38
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Вообще-то все расчёты и ведутся в копейках, но увы может быть такое, что нужно нецелое число копеек (например обмен валюты по курсу 5.065234152).


Представляю себе надпись на Сбер. Банке "Курс валют: 1 $ = 26.9445065234152 руб.";

Может можно держать курс целым числом 1 Цент = Целое Коэффициент * 1 Копейку? Или если всё это дело обобщить, то необходимо научиться переводить Условные Единицы одной валюты (Копейка, десятая часть копейки, сотая часть копейки...) в Условные Единицы другой вылюты (Цент, десятая часть цента, сотая часть цента...) с помощью Целого Коэффициента;

В итоге сумму счета получать по формуле:

Сумма = Количество У.Е. * 10 ^ Экспонента Валюты;

Экспонента Валюты это -2 для копеек, -3 для десятой части копейки, -4 для сотой части копейки...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
"В любое мгновение принятия решения, лучшее, что вы можете сделать, это принять правильное решение; следующим лучшим вариантом будет принять неправильное решение, худший вариант – не принимать решения совсем" (c) Теодор Рузвельт.
Re[6]: Округление с помощью ceil...
От: -Cheese-  
Дата: 18.10.06 06:49
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Вы в нулях не ошиблись случаем?

не ошибся
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Округление с помощью ceil...
От: Аноним  
Дата: 18.10.06 06:54
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, <Аноним>, Вы писали:


А>>Вы в нулях не ошиблись случаем?

C>не ошибся

Тогда со спокойной совестью приводите к типу int и смело прибавляйте 1, так как тип double всегда что-то там имеет в хвосте.
Re[8]: Округление с помощью ceil...
От: -Cheese-  
Дата: 18.10.06 07:22
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Тогда со спокойной совестью приводите к типу int и смело прибавляйте 1, так как тип double всегда что-то там имеет в хвосте.

Тут...
Re[2]: Округление с помощью ceil...
Автор: -Cheese-
Дата: 17.10.06
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Округление с помощью ceil...
От: Кодт Россия  
Дата: 18.10.06 07:26
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Вообще-то все расчёты и ведутся в копейках, но увы может быть такое, что нужно нецелое число копеек (например обмен валюты по курсу 5.065234152).


Ну что же, значит вот в этом месте и нужно умножать фиксированное на плавающее и получать фиксированное, причём по тому закону, который требуется — а не по тому, который забит в FPU.
Возможно, придётся поддержать несколько фиксированных форматов — *10^-2 (валюты) и *10^-9 (коэффициенты).
Либо плавающую арифметику с целой мантиссой и десятичным порядком.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[9]: Округление с помощью ceil...
От: remark Россия http://www.1024cores.net/
Дата: 18.10.06 07:47
Оценка:
Здравствуйте, -Cheese-, Вы писали:

C>Здравствуйте, Кодт, Вы писали:

К>>Здравствуйте, -Cheese-, Вы писали:
C>>>объясни попробуй клиенту про двоичное представление числа с плавающей точкой много нового о себе услышишь
C>>>ну да ладно... будем вводить эпсилон промежуток
К>>А может быть, сделать арифметику с фиксированной точкой? Грубо говоря, считать всё в int64 в копейках.

C>Вообще-то все расчёты и ведутся в копейках, но увы может быть такое, что нужно нецелое число копеек (например обмен валюты по курсу 5.065234152).


А числа плавающей запятой всё равно ничего не решат, только усугубят, т.к. точность всё равно конечная. Т.е. любой курс конвертации и сумму точно всё равно не представишь. Всё равно не каждое число можно ровно поделить на 2 части. Всё равно если с числом попроизводить какие-то вычисления и ожидать получить ровно 2,9, можешь получить 3,1.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Округление с помощью ceil...
От: Axc  
Дата: 18.10.06 07:58
Оценка:
Здравствуйте, <Аноним>, Вы писали:

Axc>>Я бы делал так:

Axc>>
Axc>>    const double accuracy = 1E-6;
Axc>>    double x = 800.0;
Axc>>    double y = 5.065;
Axc>>    double z1 = ceil(x * y * (1 - accuracy));
Axc>>    double z2 = x * y;
Axc>>    double z3 = floor(x * y * (1 + accuracy));
Axc>>


А>1) почему accuracy = 1E-6

Ни почему. Постановка задачи на тот момент еще не была уточнена. Соответственно, нужная точность была взята с потолка и задана константой. Вообще же, данный способ годится для научных расчетов, но не для денег.
А>2) почему в одном случае 1-accuracy, а в другом 1+accuracy.
Потому что ceil надо брать от числа чуть меньшего, а floor от чуть большего.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.