А>нужно округлить обнулив все разряды, начиная от 10^-3, А>как обычно это делают, учитывая что "v" может быть отрицательной.
double mean = 100;
v = ( v < 0 ? ceil( v * mean ) : floor( v * mean )) / mean;
Re[2]: округление младшего разряда
От:
Аноним
Дата:
07.07.08 13:57
Оценка:
Здравствуйте, Were, Вы писали:
W>Здравствуйте, Аноним, Вы писали:
А>>есть А>>
А>>double v;
А>>
А>>нужно округлить обнулив все разряды, начиная от 10^-3, А>>как обычно это делают, учитывая что "v" может быть отрицательной.
W>
W>double mean = 100;
W>v = ( v < 0 ? ceil( v * mean ) : floor( v * mean )) / mean;
W>
да, но здесь используется умножение и деление,
а нельзя обойтись без них, скажем прибавить или отнять 0.005,
а потом просто как-нибудь обнулить то что не нужно
Здравствуйте, <Аноним>, Вы писали:
А>да, но здесь используется умножение и деление, А>а нельзя обойтись без них, скажем прибавить или отнять 0.005, А>а потом просто как-нибудь обнулить то что не нужно
Нужно понимать устройство плавающей арифметики. Если коротко, то: нет, "просто как-нибудь" нельзя.
А ещё замечу, что 0.005 непредставимо в double, поэтому обязательно возникнут погрешности. Где эти погрешности вылезут — нужно смотреть на твои дальнейшие действия.
Если же тебе просто нужно вывести в строку (или на экран) — то смотри спецификацию форматов у printf и манипуляторы вывода у iostream'ов (setw, setprecision).
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: округление младшего разряда
От:
Аноним
Дата:
08.07.08 03:42
Оценка:
Здравствуйте, Аноним, Вы писали:
А>нужно округлить обнулив все разряды, начиная от 10^-3, А>как обычно это делают, учитывая что "v" может быть отрицательной.
Для округления чисел с плавающей точкой, ни в коем случае
нельзя использовать деление, я бы рекомендовал перейти в
область строковой конверсии. Вы берете число
double dValue = 345.6763880009999
Int64 nValue = (Int64)(dValue * 10000); // множитель точности числа
string sVal = DoubleToString(nValue);
эта функция должна выдать строку типа 3456764(5).
затем конвертируешь ее обратно в добл
без деления.
Здравствуйте, <Аноним>, Вы писали:
А>Для округления чисел с плавающей точкой, ни в коем случае А>нельзя использовать деление А>А>string sVal = DoubleToString(nValue); А>затем конвертируешь ее обратно в добл без деления.
А вот в процессе конвертации деления у тебя не повылазят?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: округление младшего разряда
От:
Аноним
Дата:
08.07.08 06:16
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>нужно округлить обнулив все разряды, начиная от 10^-3, А>>как обычно это делают, учитывая что "v" может быть отрицательной.
А>Для округления чисел с плавающей точкой, ни в коем случае А>нельзя использовать деление, я бы рекомендовал перейти в А>область строковой конверсии. Вы берете число А>double dValue = 345.6763880009999 А>Int64 nValue = (Int64)(dValue * 10000); // множитель точности числа А>string sVal = DoubleToString(nValue); А>эта функция должна выдать строку типа 3456764(5). А>затем конвертируешь ее обратно в добл А>без деления.
шутка?
мне кажется все это будет работать намного дольше, чем деление и умножение?
Здравствуйте, Аноним, Вы писали:
А>Для округления чисел с плавающей точкой, ни в коем случае А>нельзя использовать деление, я бы рекомендовал перейти в А>область строковой конверсии. Вы берете число А>double dValue = 345.6763880009999 А>Int64 nValue = (Int64)(dValue * 10000); // множитель точности числа
Точности int64 может не хватить для представления double. Например когда dValue = 1e100;
А>string sVal = DoubleToString(nValue);
Не знаю, что за функция, но во-первых ее аргумент не double, а int64, а во-вторых для перевода числа в строку с десятичной записью нужно использовать не одно деление )
А>эта функция должна выдать строку типа 3456764(5). А>затем конвертируешь ее обратно в добл А>без деления.
Если не нравится деление можно умножать на обратную величину точности, которую посчитать заранее.
Re[4]: округление младшего разряда
От:
Аноним
Дата:
08.07.08 06:51
Оценка:
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, <Аноним>, Вы писали:
А>>да, но здесь используется умножение и деление, А>>а нельзя обойтись без них, скажем прибавить или отнять 0.005, А>>а потом просто как-нибудь обнулить то что не нужно
К>Нужно понимать устройство плавающей арифметики. Если коротко, то: нет, "просто как-нибудь" нельзя. К>А ещё замечу, что 0.005 непредставимо в double, поэтому обязательно возникнут погрешности. Где эти погрешности вылезут — нужно смотреть на твои дальнейшие действия.
Исходная задача, есть итерационный алгоритм, и он накапливает погрешность,
надо время от времени можно и на каждом шаге, отбрасывать ненужные знаки после запятой,
я так посчитал, что это начиная от скажем 10^-3, в принципе и 2^-10 меня тоже устроит.
если требования к округлению сместить с десятичной системы в двоичную это поможет
предложить более эффективный алгоритм округления?
Здравствуйте, <Аноним>, Вы писали:
А>Исходная задача, есть итерационный алгоритм, и он накапливает погрешность, А>надо время от времени можно и на каждом шаге, отбрасывать ненужные знаки после запятой,
Но ведь округление только увеличивает погрешность?
А кстати, что за формула?
А>я так посчитал, что это начиная от скажем 10^-3, в принципе и 2^-10 меня тоже устроит. А>если требования к округлению сместить с десятичной системы в двоичную это поможет предложить более эффективный алгоритм округления?
В принципе, да.
Начиная с того, что можно руками распотрошить двоичное представление числа и обнулить соответствующие разряды мантиссы (в зависимости от порядка, естественно).
Либо похимичить с frexp() / ldexp(). С ходу не скажу формулу.
Здравствуйте, Аноним, Вы писали:
А>если требования к округлению сместить с десятичной системы в двоичную это поможет А>предложить более эффективный алгоритм округления?
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, <Аноним>, Вы писали:
А>>Исходная задача, есть итерационный алгоритм, и он накапливает погрешность, А>>надо время от времени можно и на каждом шаге, отбрасывать ненужные знаки после запятой,
К>Но ведь округление только увеличивает погрешность? К>А кстати, что за формула?
цифровой фильтр, сглаживает экспериментальные данные, точность в 10^-3 недостижима из-за инструментальной погрешности,
формула довольно большая, типа
x_вспомогательная_1 = сумма произведений
x_вспомогательная_2 = сумма произведений
x_результат = ...
те кто спроектировали этот фильтр (подобрали формулу и коэфиценты)
высказали предположение что фильтр будет накапливать погрешность,
и хорошо бы незначимые разряды обнулять.