Здравствуйте, cppguard, Вы писали: C>>>fixed-point CC>>аналог 1.001 C>Так и запишем — матчасть не выучил
Я на fixed point рендерер на асме написал в середине 90х.
Ты же походу и читать не умеешь и матчасть совершенно не знаешь, раз вообще не понял про что была речь.
Ну да ладно.
Начнём по порядку:
1. Что оно выведет для Q<uint8_t, 3> ((2 << 3) + 1) и что должно было вывести?
3. Что оно выведет для Q<uint32_t, 8> ((2 << 8) + 1) и что должно было вывести?
2. Что оно выведет для Q<uint32_t, 16> ((2 << 16) + 1) и что должно было вывести?
спойлеры
1. Выводит 2.0 вместо 2.125. В коде довольно очевидный баг.
2. Выводит (после исправления бага) 2.390625 вместо 2.00390625 ибо ведушие нули протерялись при выводе целого
3. Выводит феерическое 2.-2030932031 вместо 2.0000152587890625 ибо acc переполняется а потом ты это ещё и в signed кастишь, ну и нули протеряны всё равно
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, cppguard, Вы писали:
C>Накидал тут на коленке код для вывода вещественных чисел с фиксированной запятой в привычном виде. Вышло как-то слишком просто. Имеет право на жизнь?
Не очень, мягко говоря
Фиксированная точка (запятая) полезна в первую очередь для бухгалтерии/финансов, а там все числа принудительно десятичные. У тебя же рассчитано на двоичку. Я просто не могу себе представить домен, для которого такое нужно. Если какие-нибудь ситуации типа "с датчика снимаем 10 двоичных цифр дробной части ибо АЦП", то для таких лучше форматировать в шестнадцатиричную — типа значение "0x23.fc", а не в десятичную.
Но это особые ситуации и для них вообще неизвестно, стоит ли так стараться.
А для десятичной точки тебе нужно деление на 10**N чтобы нормально отображать. Вот тут можно средствами C++ догнать это до константных операций (деление на константу через обратное умножение).
Про ошибки в коде тебе сказали, а как общий принцип — тесты и ещё раз тесты! Задача такая, что сделать ошибку тривиально. Поэтому все и основные, и маргинальные случаи — подкрепить тестами.
Здравствуйте, CreatorCray, Вы писали: CC>Ты же походу и читать не умеешь и матчасть совершенно не знаешь, раз вообще не понял про что была речь. CC>Ну да ладно.
1.001 непредставимо в виде двоичной дроби. О чём речь? Или вопрос был про 0b1001? CC>
спойлеры
CC>1. Выводит 2.0 вместо 2.125. В коде довольно очевидный баг. CC>2. Выводит (после исправления бага) 2.390625 вместо 2.00390625 ибо ведушие нули протерялись при выводе целого CC>3. Выводит феерическое 2.-2030932031 вместо 2.0000152587890625 ибо acc переполняется а потом ты это ещё и в signed кастишь, ну и нули протеряны всё равно
За тестирование спасибо. Насчёт переполнения — предполагается работа только с uint8_t и форматами чисел Q4.4 и Q1.7, остальное не интересует, поэтому я и не особо старался.
Здравствуйте, netch80, Вы писали:
N>Фиксированная точка (запятая) полезна в первую очередь для бухгалтерии/финансов, а там все числа принудительно десятичные. У тебя же рассчитано на двоичку. Я просто не могу себе представить домен, для которого такое нужно. Если какие-нибудь ситуации типа "с датчика снимаем 10 двоичных цифр дробной части ибо АЦП", то для таких лучше форматировать в шестнадцатиричную — типа значение "0x23.fc", а не в десятичную.
Это нужно для отладки математики с фиксированной точкой на микроконтроллерах с аппаратным умножением.
N>Про ошибки в коде тебе сказали, а как общий принцип — тесты и ещё раз тесты! Задача такая, что сделать ошибку тривиально. Поэтому все и основные, и маргинальные случаи — подкрепить тестами.
Хорошо, но вопрос не об этом был. Если исправить ошибку, то код работает, но при этом он довольно компактен. А если загуглить "fixed-point number to string", то находятся какие-то монстры. Поскольку я не считаю себя мега-гуру, то решил спросить у сообщества — правильно ли я делаю.
Здравствуйте, cppguard, Вы писали:
N>>Фиксированная точка (запятая) полезна в первую очередь для бухгалтерии/финансов, а там все числа принудительно десятичные. У тебя же рассчитано на двоичку. Я просто не могу себе представить домен, для которого такое нужно. Если какие-нибудь ситуации типа "с датчика снимаем 10 двоичных цифр дробной части ибо АЦП", то для таких лучше форматировать в шестнадцатиричную — типа значение "0x23.fc", а не в десятичную. C>Это нужно для отладки математики с фиксированной точкой на микроконтроллерах с аппаратным умножением.
Тогда да, особый случай.
Ну точно надо в hex всё вводить и выводить. В крайнем случае в чистой двоичке.
Но не в десятичке, со всеми этими 0.0009765625 ты повесишься быстрее, чем отладишь.
N>>Про ошибки в коде тебе сказали, а как общий принцип — тесты и ещё раз тесты! Задача такая, что сделать ошибку тривиально. Поэтому все и основные, и маргинальные случаи — подкрепить тестами. C>Хорошо, но вопрос не об этом был. Если исправить ошибку, то код работает, но при этом он довольно компактен. А если загуглить "fixed-point number to string", то находятся какие-то монстры. Поскольку я не считаю себя мега-гуру, то решил спросить у сообщества — правильно ли я делаю.
Я думаю, потому и монстры, что они десятичные. А у тебя другая цель.
Здравствуйте, T4r4sB, Вы писали:
TB>В виде double оно тоже не представимо но это не мешает им пользоваться. TB>Очевидно речь шла про ближайшее приближение к этому числу
Вообще не очевидно. Ближайшее с какой стороны? Для fixed-point неопределены всякие epsilon и так далее. Да и процедуру конвертации я не приводил, чтобы давать такой тест. К чему вообще этот вопрос был?
Здравствуйте, netch80, Вы писали:
N>Тогда да, особый случай. N>Ну точно надо в hex всё вводить и выводить. В крайнем случае в чистой двоичке. N>Но не в десятичке, со всеми этими 0.0009765625 ты повесишься быстрее, чем отладишь.
Вот взять реальный пример. Есть даные магнитометра — XYZ, нужно перевести эти значения в углы Эйлера. Математика вся с фиксированной точкой, и глазами отлаживать удобно, смотря именно на десятичные значения, потому что в голове идёт привязка к радианам. Я уверен, что это лишь вопрос надроча, но для себя я пока не представляю отладку математики в шеснадцатеричных значениях.
Здравствуйте, cppguard, Вы писали:
C>Накидал тут на коленке код для вывода вещественных чисел с фиксированной запятой в привычном виде. Вышло как-то слишком просто. Имеет право на жизнь? C>...
Здравствуйте, cppguard, Вы писали:
C>Вот взять реальный пример. Есть даные магнитометра — XYZ, нужно перевести эти значения в углы Эйлера. Математика вся с фиксированной точкой, и глазами отлаживать удобно, смотря именно на десятичные значения, потому что в голове идёт привязка к радианам. Я уверен, что это лишь вопрос надроча, но для себя я пока не представляю отладку математики в шеснадцатеричных значениях.
Для отладки чтобы глазами смотреть — конвертим во float, печатаем sprintf'ом
Здравствуйте, T4r4sB, Вы писали:
TB>Для дабла все то же самое, и?
Что я должен ответить? Для моих задач писать процедуру преобразования из обыкновенной десятичной дроби в fixed-point нецелесообразоно от слова совсем, поэтому я не знаю, как 1.001 будет выглядеть в формате Q4.4.
Здравствуйте, netch80, Вы писали:
N>Фиксированная точка (запятая) полезна в первую очередь для бухгалтерии/финансов, а там все числа принудительно десятичные. У тебя же рассчитано на двоичку. Я просто не могу себе представить домен, для которого такое нужно. Если какие-нибудь ситуации типа "с датчика снимаем 10 двоичных цифр дробной части ибо АЦП", то для таких лучше форматировать в шестнадцатиричную — типа значение "0x23.fc", а не в десятичную. N>Но это особые ситуации и для них вообще неизвестно, стоит ли так стараться.
Я на полном серьезе использовал фиксированную точку в играх.
Причины две:
1. На моих железках она работала быстрее плавучки, особенно если учесть операции округления
2. Гарантированное воспроизведение результата на любой машине. Для реализации демок/реплеев важно. Я даже сетевой код на этом обосновывал — передавать по сети только команды игрока, а дальше оба компа по ним одинаково воспроизведут изменения в игровом мире, без единого бита рассинхрона
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, cppguard, Вы писали:
C>За тестирование спасибо. Насчёт переполнения — предполагается работа только с uint8_t и форматами чисел Q4.4 и Q1.7, остальное не интересует, поэтому я и не особо старался.
Я правильно понимаю, что:
Q4.4 — это две таблицы по 16 элементов.
Q1.7 — это 0 или 1 и таблица на 128 элементов.
?
Здравствуйте, T4r4sB, Вы писали:
TB>Я на полном серьезе использовал фиксированную точку в играх. TB>Причины две: TB>1. На моих железках она работала быстрее плавучки, особенно если учесть операции округления
ok, возможно.
TB>2. Гарантированное воспроизведение результата на любой машине. Для реализации демок/реплеев важно. Я даже сетевой код на этом обосновывал — передавать по сети только команды игрока, а дальше оба компа по ним одинаково воспроизведут изменения в игровом мире, без единого бита рассинхрона
Вот тут... в пределах корректных операций IEEE754 простые операции (арифметика плюс какой-нибудь sqrt) должны считаться везде одинаково, расхождения должны начаться где-то с sin, log* и дальше в трансцедентные функции. И то насчёт sin не уверен.
Хотя, если где-то тупые реализации, ХЗ...
Но это значит что вы сделали свои реализации — пусть с погрешностями, но одинаковые.
Здравствуйте, netch80, Вы писали:
N>Вот тут... в пределах корректных операций IEEE754 простые операции (арифметика плюс какой-нибудь sqrt) должны считаться везде одинаково, расхождения должны начаться где-то с sin, log* и дальше в трансцедентные функции. И то насчёт sin не уверен. N>Хотя, если где-то тупые реализации, ХЗ... N>Но это значит что вы сделали свои реализации — пусть с погрешностями, но одинаковые.
А вот хрен. Расхождения зависят не только от режима компиляции.
Даже одна и та же формула в разных контекстах может выдать разный результат на одних входных данных.
Так что не доверяй плавучке
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, cppguard, Вы писали:
C>Накидал тут на коленке код для вывода вещественных чисел с фиксированной запятой в привычном виде. Вышло как-то слишком просто. Имеет право на жизнь?
fcvt можно использовать, там можно указывать сколько цифр после запятой обрабатывать. Только функция точку в строку не пишет, но честно возвращает, где она должна стоять. Так что дополнительные телодвижения нужны, чтобы её туда вертать взад.